mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-07-15 08:32:42 +08:00
feat(mbedtls): bring mbedtls and openssl based on mbedtls from esp-idf
Commit ID: 97959e77. Using submodule instead of source code. It is brought from esp-idf, and some origin dependent code or configuration of hardware have not been removed. But it maybe not affect using at the ESP8266 platform.
This commit is contained in:
41
components/mbedtls/CMakeLists.txt
Normal file
41
components/mbedtls/CMakeLists.txt
Normal file
@ -0,0 +1,41 @@
|
||||
idf_component_register(INCLUDE_DIRS "port/include" "mbedtls/include"
|
||||
REQUIRES lwip)
|
||||
|
||||
# Only build mbedtls libraries
|
||||
set(ENABLE_TESTING CACHE BOOL OFF)
|
||||
set(ENABLE_PROGRAMS CACHE BOOL OFF)
|
||||
|
||||
# Needed to for include_next includes to work from within mbedtls
|
||||
include_directories("${COMPONENT_DIR}/port/include")
|
||||
|
||||
# Import mbedtls library targets
|
||||
add_subdirectory(mbedtls)
|
||||
|
||||
# Use port specific implementation of net_socket.c instead of one from mbedtls
|
||||
get_target_property(src_tls mbedtls SOURCES)
|
||||
list(REMOVE_ITEM src_tls net_sockets.c)
|
||||
set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls})
|
||||
|
||||
set(mbedtls_targets mbedtls mbedcrypto mbedx509)
|
||||
|
||||
# Add port files to mbedtls targets
|
||||
target_sources(mbedtls PRIVATE "${COMPONENT_DIR}/port/mbedtls_debug.c"
|
||||
"${COMPONENT_DIR}/port/net_sockets.c")
|
||||
|
||||
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_bignum.c"
|
||||
"${COMPONENT_DIR}/port/esp_hardware.c"
|
||||
"${COMPONENT_DIR}/port/esp_mem.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha1.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha256.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha512.c"
|
||||
"${COMPONENT_DIR}/port/esp_timing.c"
|
||||
"${COMPONENT_DIR}/port/esp32/aes.c"
|
||||
"${COMPONENT_DIR}/port/esp32/sha.c")
|
||||
|
||||
foreach(target ${mbedtls_targets})
|
||||
target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h")
|
||||
endforeach()
|
||||
|
||||
# Link mbedtls libraries to component library
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE ${mbedtls_targets})
|
599
components/mbedtls/Kconfig
Normal file
599
components/mbedtls/Kconfig
Normal file
@ -0,0 +1,599 @@
|
||||
menu "mbedTLS"
|
||||
|
||||
choice MBEDTLS_MEM_ALLOC_MODE
|
||||
prompt "Memory allocation strategy"
|
||||
default MBEDTLS_INTERNAL_MEM_ALLOC
|
||||
help
|
||||
Allocation strategy for mbedTLS, essentially provides ability to
|
||||
allocate all required dynamic allocations from,
|
||||
|
||||
- Internal DRAM memory only
|
||||
- External SPIRAM memory only
|
||||
- Either internal or external memory based on default malloc()
|
||||
behavior in ESP-IDF
|
||||
- Custom allocation mode, by overwriting calloc()/free() using
|
||||
mbedtls_platform_set_calloc_free() function
|
||||
|
||||
Recommended mode here is always internal, since that is most preferred
|
||||
from security perspective. But if application requirement does not
|
||||
allow sufficient free internal memory then alternate mode can be
|
||||
selected.
|
||||
|
||||
config MBEDTLS_INTERNAL_MEM_ALLOC
|
||||
bool "Internal memory"
|
||||
|
||||
config MBEDTLS_EXTERNAL_MEM_ALLOC
|
||||
bool "External SPIRAM"
|
||||
depends on ESP32_SPIRAM_SUPPORT
|
||||
|
||||
config MBEDTLS_DEFAULT_MEM_ALLOC
|
||||
bool "Default alloc mode"
|
||||
|
||||
config MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
bool "Custom alloc mode"
|
||||
|
||||
endchoice #MBEDTLS_MEM_ALLOC_MODE
|
||||
|
||||
config MBEDTLS_SSL_MAX_CONTENT_LEN
|
||||
int "TLS maximum message content length"
|
||||
default 16384
|
||||
range 512 16384
|
||||
depends on !MBEDTLS_ASYMMETRIC_CONTENT_LEN
|
||||
help
|
||||
Maximum TLS message length (in bytes) supported by mbedTLS.
|
||||
|
||||
16384 is the default and this value is required to comply
|
||||
fully with TLS standards.
|
||||
|
||||
However you can set a lower value in order to save RAM. This
|
||||
is safe if the other end of the connection supports Maximum
|
||||
Fragment Length Negotiation Extension (max_fragment_length,
|
||||
see RFC6066) or you know for certain that it will never send a
|
||||
message longer than a certain number of bytes.
|
||||
|
||||
If the value is set too low, symptoms are a failed TLS
|
||||
handshake or a return value of MBEDTLS_ERR_SSL_INVALID_RECORD
|
||||
(-0x7200).
|
||||
|
||||
config MBEDTLS_ASYMMETRIC_CONTENT_LEN
|
||||
bool "Asymmetric in/out fragment length"
|
||||
default y
|
||||
help
|
||||
If enabled, this option allows customizing TLS in/out fragment length
|
||||
in asymmetric way. Please note that enabling this with default values
|
||||
saves 12KB of dynamic memory per TLS connection.
|
||||
|
||||
config MBEDTLS_SSL_IN_CONTENT_LEN
|
||||
int "TLS maximum incoming fragment length"
|
||||
default 16384
|
||||
range 512 16384
|
||||
depends on MBEDTLS_ASYMMETRIC_CONTENT_LEN
|
||||
help
|
||||
This defines maximum incoming fragment length, overriding default
|
||||
maximum content length (MBEDTLS_SSL_MAX_CONTENT_LEN).
|
||||
|
||||
config MBEDTLS_SSL_OUT_CONTENT_LEN
|
||||
int "TLS maximum outgoing fragment length"
|
||||
default 4096
|
||||
range 512 16384
|
||||
depends on MBEDTLS_ASYMMETRIC_CONTENT_LEN
|
||||
help
|
||||
This defines maximum outgoing fragment length, overriding default
|
||||
maximum content length (MBEDTLS_SSL_MAX_CONTENT_LEN).
|
||||
|
||||
config MBEDTLS_DEBUG
|
||||
bool "Enable mbedTLS debugging"
|
||||
default n
|
||||
help
|
||||
Enable mbedTLS debugging functions at compile time.
|
||||
|
||||
If this option is enabled, you can include
|
||||
"mbedtls/esp_debug.h" and call mbedtls_esp_enable_debug_log()
|
||||
at runtime in order to enable mbedTLS debug output via the ESP
|
||||
log mechanism.
|
||||
|
||||
choice MBEDTLS_DEBUG_LEVEL
|
||||
bool "Set mbedTLS debugging level"
|
||||
depends on MBEDTLS_DEBUG
|
||||
default MBEDTLS_DEBUG_LEVEL_VERBOSE
|
||||
help
|
||||
Set mbedTLS debugging level
|
||||
|
||||
config MBEDTLS_DEBUG_LEVEL_WARN
|
||||
bool "Warning"
|
||||
config MBEDTLS_DEBUG_LEVEL_INFO
|
||||
bool "Info"
|
||||
config MBEDTLS_DEBUG_LEVEL_DEBUG
|
||||
bool "Debug"
|
||||
config MBEDTLS_DEBUG_LEVEL_VERBOSE
|
||||
bool "Verbose"
|
||||
endchoice
|
||||
|
||||
config MBEDTLS_DEBUG_LEVEL
|
||||
int
|
||||
default 1 if MBEDTLS_DEBUG_LEVEL_WARN
|
||||
default 2 if MBEDTLS_DEBUG_LEVEL_INFO
|
||||
default 3 if MBEDTLS_DEBUG_LEVEL_DEBUG
|
||||
default 4 if MBEDTLS_DEBUG_LEVEL_VERBOSE
|
||||
|
||||
config MBEDTLS_HARDWARE_AES
|
||||
bool "Enable hardware AES acceleration"
|
||||
default y
|
||||
help
|
||||
Enable hardware accelerated AES encryption & decryption.
|
||||
|
||||
Note that if the ESP32 CPU is running at 240MHz, hardware AES does not
|
||||
offer any speed boost over software AES.
|
||||
|
||||
config MBEDTLS_HARDWARE_MPI
|
||||
bool "Enable hardware MPI (bignum) acceleration"
|
||||
default n
|
||||
help
|
||||
Enable hardware accelerated multiple precision integer operations.
|
||||
|
||||
Hardware accelerated multiplication, modulo multiplication,
|
||||
and modular exponentiation for up to 4096 bit results.
|
||||
|
||||
These operations are used by RSA.
|
||||
|
||||
config MBEDTLS_MPI_USE_INTERRUPT
|
||||
bool "Use interrupt for MPI operations"
|
||||
depends on MBEDTLS_HARDWARE_MPI
|
||||
default n
|
||||
help
|
||||
Use an interrupt to coordinate MPI operations.
|
||||
|
||||
This allows other code to run on the CPU while an MPI operation is pending.
|
||||
Otherwise the CPU busy-waits.
|
||||
|
||||
config MBEDTLS_HARDWARE_SHA
|
||||
bool "Enable hardware SHA acceleration"
|
||||
default n
|
||||
help
|
||||
Enable hardware accelerated SHA1, SHA256, SHA384 & SHA512 in mbedTLS.
|
||||
|
||||
Due to a hardware limitation, hardware acceleration is only
|
||||
guaranteed if SHA digests are calculated one at a time. If more
|
||||
than one SHA digest is calculated at the same time, one will
|
||||
be calculated fully in hardware and the rest will be calculated
|
||||
(at least partially calculated) in software. This happens automatically.
|
||||
|
||||
SHA hardware acceleration is faster than software in some situations but
|
||||
slower in others. You should benchmark to find the best setting for you.
|
||||
|
||||
config MBEDTLS_HAVE_TIME
|
||||
bool "Enable mbedtls time"
|
||||
depends on !ESP32_TIME_SYSCALL_USE_NONE
|
||||
default y
|
||||
help
|
||||
System has time.h and time().
|
||||
The time does not need to be correct, only time differences are used.
|
||||
|
||||
config MBEDTLS_HAVE_TIME_DATE
|
||||
bool "Enable mbedtls certificate expiry check"
|
||||
depends on MBEDTLS_HAVE_TIME
|
||||
default n
|
||||
help
|
||||
System has time.h and time(), gmtime() and the clock is correct.
|
||||
The time needs to be correct (not necesarily very accurate, but at least
|
||||
the date should be correct). This is used to verify the validity period of
|
||||
X.509 certificates.
|
||||
|
||||
It is suggested that you should get the real time by "SNTP".
|
||||
|
||||
choice MBEDTLS_TLS_MODE
|
||||
bool "TLS Protocol Role"
|
||||
default MBEDTLS_TLS_SERVER_AND_CLIENT
|
||||
help
|
||||
mbedTLS can be compiled with protocol support for the TLS
|
||||
server, TLS client, or both server and client.
|
||||
|
||||
Reducing the number of TLS roles supported saves code size.
|
||||
|
||||
config MBEDTLS_TLS_SERVER_AND_CLIENT
|
||||
bool "Server & Client"
|
||||
select MBEDTLS_TLS_SERVER
|
||||
select MBEDTLS_TLS_CLIENT
|
||||
config MBEDTLS_TLS_SERVER_ONLY
|
||||
bool "Server"
|
||||
select MBEDTLS_TLS_SERVER
|
||||
config MBEDTLS_TLS_CLIENT_ONLY
|
||||
bool "Client"
|
||||
select MBEDTLS_TLS_CLIENT
|
||||
config MBEDTLS_TLS_DISABLED
|
||||
bool "None"
|
||||
|
||||
endchoice
|
||||
|
||||
config MBEDTLS_TLS_SERVER
|
||||
bool
|
||||
select MBEDTLS_TLS_ENABLED
|
||||
config MBEDTLS_TLS_CLIENT
|
||||
bool
|
||||
select MBEDTLS_TLS_ENABLED
|
||||
config MBEDTLS_TLS_ENABLED
|
||||
bool
|
||||
|
||||
menu "TLS Key Exchange Methods"
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
|
||||
config MBEDTLS_PSK_MODES
|
||||
bool "Enable pre-shared-key ciphersuites"
|
||||
default n
|
||||
help
|
||||
Enable to show configuration for different types of pre-shared-key TLS authentatication methods.
|
||||
|
||||
Leaving this options disabled will save code size if they are not used.
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_PSK
|
||||
bool "Enable PSK based ciphersuite modes"
|
||||
depends on MBEDTLS_PSK_MODES
|
||||
default n
|
||||
help
|
||||
Enable to support symmetric key PSK (pre-shared-key) TLS key exchange modes.
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_DHE_PSK
|
||||
bool "Enable DHE-PSK based ciphersuite modes"
|
||||
depends on MBEDTLS_PSK_MODES
|
||||
default y
|
||||
help
|
||||
Enable to support Diffie-Hellman PSK (pre-shared-key) TLS authentication modes.
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_ECDHE_PSK
|
||||
bool "Enable ECDHE-PSK based ciphersuite modes"
|
||||
depends on MBEDTLS_PSK_MODES && MBEDTLS_ECDH_C
|
||||
default y
|
||||
help
|
||||
Enable to support Elliptic-Curve-Diffie-Hellman PSK (pre-shared-key) TLS authentication modes.
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_RSA_PSK
|
||||
bool "Enable RSA-PSK based ciphersuite modes"
|
||||
depends on MBEDTLS_PSK_MODES
|
||||
default y
|
||||
help
|
||||
Enable to support RSA PSK (pre-shared-key) TLS authentication modes.
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_RSA
|
||||
bool "Enable RSA-only based ciphersuite modes"
|
||||
default y
|
||||
help
|
||||
Enable to support ciphersuites with prefix TLS-RSA-WITH-
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_DHE_RSA
|
||||
bool "Enable DHE-RSA based ciphersuite modes"
|
||||
default y
|
||||
help
|
||||
Enable to support ciphersuites with prefix TLS-DHE-RSA-WITH-
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE
|
||||
bool "Support Elliptic Curve based ciphersuites"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable to show Elliptic Curve based ciphersuite mode options.
|
||||
|
||||
Disabling all Elliptic Curve ciphersuites saves code size and
|
||||
can give slightly faster TLS handshakes, provided the server supports
|
||||
RSA-only ciphersuite modes.
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_ECDHE_RSA
|
||||
bool "Enable ECDHE-RSA based ciphersuite modes"
|
||||
depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C
|
||||
default y
|
||||
help
|
||||
Enable to support ciphersuites with prefix TLS-ECDHE-RSA-WITH-
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
|
||||
bool "Enable ECDHE-ECDSA based ciphersuite modes"
|
||||
depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C && MBEDTLS_ECDSA_C
|
||||
default y
|
||||
help
|
||||
Enable to support ciphersuites with prefix TLS-ECDHE-RSA-WITH-
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA
|
||||
bool "Enable ECDH-ECDSA based ciphersuite modes"
|
||||
depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C && MBEDTLS_ECDSA_C
|
||||
default y
|
||||
help
|
||||
Enable to support ciphersuites with prefix TLS-ECDHE-RSA-WITH-
|
||||
|
||||
config MBEDTLS_KEY_EXCHANGE_ECDH_RSA
|
||||
bool "Enable ECDH-RSA based ciphersuite modes"
|
||||
depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C
|
||||
default y
|
||||
help
|
||||
Enable to support ciphersuites with prefix TLS-ECDHE-RSA-WITH-
|
||||
|
||||
endmenu # TLS key exchange modes
|
||||
|
||||
config MBEDTLS_SSL_RENEGOTIATION
|
||||
bool "Support TLS renegotiation"
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
default y
|
||||
help
|
||||
The two main uses of renegotiation are (1) refresh keys on long-lived
|
||||
connections and (2) client authentication after the initial handshake.
|
||||
If you don't need renegotiation, disabling it will save code size and
|
||||
reduce the possibility of abuse/vulnerability.
|
||||
|
||||
config MBEDTLS_SSL_PROTO_SSL3
|
||||
bool "Legacy SSL 3.0 support"
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
default n
|
||||
help
|
||||
Support the legacy SSL 3.0 protocol. Most servers will speak a newer
|
||||
TLS protocol these days.
|
||||
|
||||
config MBEDTLS_SSL_PROTO_TLS1
|
||||
bool "Support TLS 1.0 protocol"
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
default y
|
||||
|
||||
config MBEDTLS_SSL_PROTO_TLS1_1
|
||||
bool "Support TLS 1.1 protocol"
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
default y
|
||||
|
||||
config MBEDTLS_SSL_PROTO_TLS1_2
|
||||
bool "Support TLS 1.2 protocol"
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
default y
|
||||
|
||||
config MBEDTLS_SSL_PROTO_DTLS
|
||||
bool "Support DTLS protocol (all versions)"
|
||||
default n
|
||||
depends on MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2
|
||||
help
|
||||
Requires TLS 1.1 to be enabled for DTLS 1.0
|
||||
Requires TLS 1.2 to be enabled for DTLS 1.2
|
||||
|
||||
config MBEDTLS_SSL_ALPN
|
||||
bool "Support ALPN (Application Layer Protocol Negotiation)"
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
default y
|
||||
help
|
||||
Disabling this option will save some code size if it is not needed.
|
||||
|
||||
config MBEDTLS_CLIENT_SSL_SESSION_TICKETS
|
||||
bool "TLS: Client Support for RFC 5077 SSL session tickets"
|
||||
default y
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
help
|
||||
Client support for RFC 5077 session tickets. See mbedTLS documentation for more details.
|
||||
Disabling this option will save some code size.
|
||||
|
||||
config MBEDTLS_SERVER_SSL_SESSION_TICKETS
|
||||
bool "TLS: Server Support for RFC 5077 SSL session tickets"
|
||||
default y
|
||||
depends on MBEDTLS_TLS_ENABLED
|
||||
help
|
||||
Server support for RFC 5077 session tickets. See mbedTLS documentation for more details.
|
||||
Disabling this option will save some code size.
|
||||
|
||||
menu "Symmetric Ciphers"
|
||||
|
||||
config MBEDTLS_AES_C
|
||||
bool "AES block cipher"
|
||||
default y
|
||||
|
||||
config MBEDTLS_CAMELLIA_C
|
||||
bool "Camellia block cipher"
|
||||
default n
|
||||
|
||||
config MBEDTLS_DES_C
|
||||
bool "DES block cipher (legacy, insecure)"
|
||||
default n
|
||||
help
|
||||
Enables the DES block cipher to support 3DES-based TLS ciphersuites.
|
||||
|
||||
3DES is vulnerable to the Sweet32 attack and should only be enabled
|
||||
if absolutely necessary.
|
||||
|
||||
choice MBEDTLS_RC4_MODE
|
||||
prompt "RC4 Stream Cipher (legacy, insecure)"
|
||||
default MBEDTLS_RC4_DISABLED
|
||||
help
|
||||
ARCFOUR (RC4) stream cipher can be disabled entirely, enabled but not
|
||||
added to default ciphersuites, or enabled completely.
|
||||
|
||||
Please consider the security implications before enabling RC4.
|
||||
|
||||
config MBEDTLS_RC4_DISABLED
|
||||
bool "Disabled"
|
||||
config MBEDTLS_RC4_ENABLED_NO_DEFAULT
|
||||
bool "Enabled, not in default ciphersuites"
|
||||
config MBEDTLS_RC4_ENABLED
|
||||
bool "Enabled"
|
||||
endchoice
|
||||
|
||||
config MBEDTLS_BLOWFISH_C
|
||||
bool "Blowfish block cipher (read help)"
|
||||
default n
|
||||
help
|
||||
Enables the Blowfish block cipher (not used for TLS sessions.)
|
||||
|
||||
The Blowfish cipher is not used for mbedTLS TLS sessions but can be
|
||||
used for other purposes. Read up on the limitations of Blowfish (including
|
||||
Sweet32) before enabling.
|
||||
|
||||
config MBEDTLS_XTEA_C
|
||||
bool "XTEA block cipher"
|
||||
default n
|
||||
help
|
||||
Enables the XTEA block cipher.
|
||||
|
||||
|
||||
config MBEDTLS_CCM_C
|
||||
bool "CCM (Counter with CBC-MAC) block cipher modes"
|
||||
default y
|
||||
depends on MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C
|
||||
help
|
||||
Enable Counter with CBC-MAC (CCM) modes for AES and/or Camellia ciphers.
|
||||
|
||||
Disabling this option saves some code size.
|
||||
|
||||
config MBEDTLS_GCM_C
|
||||
bool "GCM (Galois/Counter) block cipher modes"
|
||||
default y
|
||||
depends on MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C
|
||||
help
|
||||
Enable Galois/Counter Mode for AES and/or Camellia ciphers.
|
||||
|
||||
This option is generally faster than CCM.
|
||||
|
||||
endmenu # Symmetric Ciphers
|
||||
|
||||
config MBEDTLS_RIPEMD160_C
|
||||
bool "Enable RIPEMD-160 hash algorithm"
|
||||
default n
|
||||
help
|
||||
Enable the RIPEMD-160 hash algorithm.
|
||||
|
||||
menu "Certificates"
|
||||
|
||||
config MBEDTLS_PEM_PARSE_C
|
||||
bool "Read & Parse PEM formatted certificates"
|
||||
default y
|
||||
help
|
||||
Enable decoding/parsing of PEM formatted certificates.
|
||||
|
||||
If your certificates are all in the simpler DER format, disabling
|
||||
this option will save some code size.
|
||||
|
||||
config MBEDTLS_PEM_WRITE_C
|
||||
bool "Write PEM formatted certificates"
|
||||
default y
|
||||
help
|
||||
Enable writing of PEM formatted certificates.
|
||||
|
||||
If writing certificate data only in DER format, disabling this
|
||||
option will save some code size.
|
||||
|
||||
config MBEDTLS_X509_CRL_PARSE_C
|
||||
bool "X.509 CRL parsing"
|
||||
default y
|
||||
help
|
||||
Support for parsing X.509 Certifificate Revocation Lists.
|
||||
|
||||
config MBEDTLS_X509_CSR_PARSE_C
|
||||
bool "X.509 CSR parsing"
|
||||
default y
|
||||
help
|
||||
Support for parsing X.509 Certifificate Signing Requests
|
||||
|
||||
endmenu # Certificates
|
||||
|
||||
menuconfig MBEDTLS_ECP_C
|
||||
bool "Elliptic Curve Ciphers"
|
||||
default y
|
||||
|
||||
config MBEDTLS_ECDH_C
|
||||
bool "Elliptic Curve Diffie-Hellman (ECDH)"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable ECDH. Needed to use ECDHE-xxx TLS ciphersuites.
|
||||
|
||||
config MBEDTLS_ECDSA_C
|
||||
bool "Elliptic Curve DSA"
|
||||
depends on MBEDTLS_ECDH_C
|
||||
default y
|
||||
help
|
||||
Enable ECDSA. Needed to use ECDSA-xxx TLS ciphersuites.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
bool "Enable SECP192R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP192R1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP224R1_ENABLED
|
||||
bool "Enable SECP224R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP224R1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
bool "Enable SECP256R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP256R1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
bool "Enable SECP384R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP384R1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||
bool "Enable SECP521R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP521R1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP192K1_ENABLED
|
||||
bool "Enable SECP192K1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP192K1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP224K1_ENABLED
|
||||
bool "Enable SECP224K1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP224K1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
||||
bool "Enable SECP256K1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for SECP256K1 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_BP256R1_ENABLED
|
||||
bool "Enable BP256R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
support for DP Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_BP384R1_ENABLED
|
||||
bool "Enable BP384R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
support for DP Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_BP512R1_ENABLED
|
||||
bool "Enable BP512R1 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
support for DP Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
bool "Enable CURVE25519 curve"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
Enable support for CURVE25519 Elliptic Curve.
|
||||
|
||||
config MBEDTLS_ECP_NIST_OPTIM
|
||||
bool "NIST 'modulo p' optimisations"
|
||||
depends on MBEDTLS_ECP_C
|
||||
default y
|
||||
help
|
||||
NIST 'modulo p' optimisations increase Elliptic Curve operation performance.
|
||||
|
||||
Disabling this option saves some code size.
|
||||
|
||||
# end of Elliptic Curve options
|
||||
|
||||
endmenu # mbedTLS
|
8
components/mbedtls/Makefile.projbuild
Normal file
8
components/mbedtls/Makefile.projbuild
Normal file
@ -0,0 +1,8 @@
|
||||
# Anyone compiling mbedTLS code needs the name of the
|
||||
# alternative config file
|
||||
CPPFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"'
|
||||
|
||||
# Catch usage of deprecated mbedTLS functions when building tests
|
||||
ifneq ("$(filter mbedtls,$(TEST_COMPONENTS_LIST))","")
|
||||
CPPFLAGS += -DMBEDTLS_DEPRECATED_WARNING
|
||||
endif
|
12
components/mbedtls/component.mk
Normal file
12
components/mbedtls/component.mk
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := port/include mbedtls/include
|
||||
|
||||
COMPONENT_SRCDIRS := mbedtls/library port port/esp32
|
||||
|
||||
COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o
|
||||
|
||||
COMPONENT_SUBMODULES += mbedtls
|
||||
|
1
components/mbedtls/mbedtls
Submodule
1
components/mbedtls/mbedtls
Submodule
Submodule components/mbedtls/mbedtls added at 97959e7791
768
components/mbedtls/port/esp32/aes.c
Normal file
768
components/mbedtls/port/esp32/aes.c
Normal file
@ -0,0 +1,768 @@
|
||||
/**
|
||||
* \brief AES block cipher, ESP32 hardware accelerated version
|
||||
* Based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016-2017, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
|
||||
*
|
||||
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
|
||||
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "esp32/aes.h"
|
||||
#include "soc/hwcrypto_periph.h"
|
||||
#include <sys/lock.h>
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
|
||||
#include "soc/cpu.h"
|
||||
#include <stdio.h>
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
|
||||
/* AES uses a spinlock mux not a lock as the underlying block operation
|
||||
only takes 208 cycles (to write key & compute block), +600 cycles
|
||||
for DPORT protection but +3400 cycles again if you use a full sized lock.
|
||||
|
||||
For CBC, CFB, etc. this may mean that interrupts are disabled for a longer
|
||||
period of time for bigger lengths. However at the moment this has to happen
|
||||
anyway due to DPORT protection...
|
||||
*/
|
||||
static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static inline bool valid_key_length(const esp_aes_context *ctx)
|
||||
{
|
||||
return ctx->key_bytes == 128/8 || ctx->key_bytes == 192/8 || ctx->key_bytes == 256/8;
|
||||
}
|
||||
|
||||
void esp_aes_acquire_hardware( void )
|
||||
{
|
||||
portENTER_CRITICAL(&aes_spinlock);
|
||||
|
||||
/* Enable AES hardware */
|
||||
periph_module_enable(PERIPH_AES_MODULE);
|
||||
}
|
||||
|
||||
void esp_aes_release_hardware( void )
|
||||
{
|
||||
/* Disable AES hardware */
|
||||
periph_module_disable(PERIPH_AES_MODULE);
|
||||
|
||||
portEXIT_CRITICAL(&aes_spinlock);
|
||||
}
|
||||
|
||||
void esp_aes_init( esp_aes_context *ctx )
|
||||
{
|
||||
bzero( ctx, sizeof( esp_aes_context ) );
|
||||
}
|
||||
|
||||
void esp_aes_free( esp_aes_context *ctx )
|
||||
{
|
||||
if ( ctx == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
bzero( ctx, sizeof( esp_aes_context ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* AES key schedule (same for encryption or decryption, as hardware handles schedule)
|
||||
*
|
||||
*/
|
||||
int esp_aes_setkey( esp_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits )
|
||||
{
|
||||
if (keybits != 128 && keybits != 192 && keybits != 256) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
ctx->key_bytes = keybits / 8;
|
||||
memcpy(ctx->key, key, ctx->key_bytes);
|
||||
ctx->key_in_hardware = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to copy key from esp_aes_context buffer
|
||||
* to hardware key registers.
|
||||
*
|
||||
* Call only while holding esp_aes_acquire_hardware().
|
||||
*/
|
||||
static void esp_aes_setkey_hardware(esp_aes_context *ctx, int mode)
|
||||
{
|
||||
const uint32_t MODE_DECRYPT_BIT = 4;
|
||||
unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT;
|
||||
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
for (int i = 0; i < ctx->key_bytes/4; ++i) {
|
||||
DPORT_REG_WRITE(AES_KEY_BASE + i * 4, *(((uint32_t *)ctx->key) + i));
|
||||
ctx->key_in_hardware += 4;
|
||||
}
|
||||
|
||||
DPORT_REG_WRITE(AES_MODE_REG, mode_reg_base + ((ctx->key_bytes / 8) - 2));
|
||||
|
||||
/* Fault injection check: all words of key data should have been written to hardware */
|
||||
if (ctx->key_in_hardware < 16
|
||||
|| ctx->key_in_hardware != ctx->key_bytes) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Run a single 16 byte block of AES, using the hardware engine.
|
||||
*
|
||||
* Call only while holding esp_aes_acquire_hardware().
|
||||
*/
|
||||
static int esp_aes_block(esp_aes_context *ctx, const void *input, void *output)
|
||||
{
|
||||
const uint32_t *input_words = (const uint32_t *)input;
|
||||
uint32_t i0, i1, i2, i3;
|
||||
uint32_t *output_words = (uint32_t *)output;
|
||||
|
||||
/* If no key is written to hardware yet, either the user hasn't called
|
||||
mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec - meaning we also don't
|
||||
know which mode to use - or a fault skipped the
|
||||
key write to hardware. Treat this as a fatal error and zero the output block.
|
||||
*/
|
||||
if (ctx->key_in_hardware != ctx->key_bytes) {
|
||||
bzero(output, 16);
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
}
|
||||
|
||||
/* Storing i0,i1,i2,i3 in registers not an array
|
||||
helps a lot with optimisations at -Os level */
|
||||
i0 = input_words[0];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE, i0);
|
||||
|
||||
i1 = input_words[1];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE + 4, i1);
|
||||
|
||||
i2 = input_words[2];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE + 8, i2);
|
||||
|
||||
i3 = input_words[3];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE + 12, i3);
|
||||
|
||||
DPORT_REG_WRITE(AES_START_REG, 1);
|
||||
|
||||
while (DPORT_REG_READ(AES_IDLE_REG) != 1) { }
|
||||
|
||||
esp_dport_access_read_buffer(output_words, AES_TEXT_BASE, 4);
|
||||
|
||||
/* Physical security check: Verify the AES accelerator actually ran, and wasn't
|
||||
skipped due to external fault injection while starting the peripheral.
|
||||
|
||||
Note that i0,i1,i2,i3 are copied from input buffer in case input==output.
|
||||
|
||||
Bypassing this check requires at least one additional fault.
|
||||
*/
|
||||
if(i0 == output_words[0] && i1 == output_words[1] && i2 == output_words[2] && i3 == output_words[3]) {
|
||||
// calling zeroing functions to narrow the
|
||||
// window for a double-fault of the abort step, here
|
||||
memset(output, 0, 16);
|
||||
mbedtls_platform_zeroize(output, 16);
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-ECB block encryption
|
||||
*/
|
||||
int esp_internal_aes_encrypt( esp_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
r = esp_aes_block(ctx, input, output);
|
||||
esp_aes_release_hardware();
|
||||
return r;
|
||||
}
|
||||
|
||||
void esp_aes_encrypt( esp_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
esp_internal_aes_encrypt(ctx, input, output);
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-ECB block decryption
|
||||
*/
|
||||
|
||||
int esp_internal_aes_decrypt( esp_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_DECRYPT);
|
||||
r = esp_aes_block(ctx, input, output);
|
||||
esp_aes_release_hardware();
|
||||
return r;
|
||||
}
|
||||
|
||||
void esp_aes_decrypt( esp_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
esp_internal_aes_decrypt(ctx, input, output);
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-ECB block encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_ecb( esp_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
esp_aes_setkey_hardware(ctx, mode);
|
||||
r = esp_aes_block(ctx, input, output);
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AES-CBC buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_cbc( esp_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int i;
|
||||
uint32_t *output_words = (uint32_t *)output;
|
||||
const uint32_t *input_words = (const uint32_t *)input;
|
||||
uint32_t *iv_words = (uint32_t *)iv;
|
||||
unsigned char temp[16];
|
||||
|
||||
if ( length % 16 ) {
|
||||
return ( ERR_ESP_AES_INVALID_INPUT_LENGTH );
|
||||
}
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, mode);
|
||||
|
||||
if ( mode == ESP_AES_DECRYPT ) {
|
||||
while ( length > 0 ) {
|
||||
memcpy(temp, input_words, 16);
|
||||
esp_aes_block(ctx, input_words, output_words);
|
||||
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
output_words[i] = output_words[i] ^ iv_words[i];
|
||||
}
|
||||
|
||||
memcpy( iv_words, temp, 16 );
|
||||
|
||||
input_words += 4;
|
||||
output_words += 4;
|
||||
length -= 16;
|
||||
}
|
||||
} else { // ESP_AES_ENCRYPT
|
||||
while ( length > 0 ) {
|
||||
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
output_words[i] = input_words[i] ^ iv_words[i];
|
||||
}
|
||||
|
||||
esp_aes_block(ctx, output_words, output_words);
|
||||
memcpy( iv_words, output_words, 16 );
|
||||
|
||||
input_words += 4;
|
||||
output_words += 4;
|
||||
length -= 16;
|
||||
}
|
||||
}
|
||||
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-CFB128 buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_cfb128( esp_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int c;
|
||||
size_t n = *iv_off;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
if ( mode == ESP_AES_DECRYPT ) {
|
||||
while ( length-- ) {
|
||||
if ( n == 0 ) {
|
||||
esp_aes_block(ctx, iv, iv);
|
||||
}
|
||||
|
||||
c = *input++;
|
||||
*output++ = (unsigned char)( c ^ iv[n] );
|
||||
iv[n] = (unsigned char) c;
|
||||
|
||||
n = ( n + 1 ) & 0x0F;
|
||||
}
|
||||
} else {
|
||||
while ( length-- ) {
|
||||
if ( n == 0 ) {
|
||||
esp_aes_block(ctx, iv, iv);
|
||||
}
|
||||
|
||||
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
|
||||
|
||||
n = ( n + 1 ) & 0x0F;
|
||||
}
|
||||
}
|
||||
|
||||
*iv_off = n;
|
||||
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-CFB8 buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_cfb8( esp_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
unsigned char c;
|
||||
unsigned char ov[17];
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
while ( length-- ) {
|
||||
memcpy( ov, iv, 16 );
|
||||
esp_aes_block(ctx, iv, iv);
|
||||
|
||||
if ( mode == ESP_AES_DECRYPT ) {
|
||||
ov[16] = *input;
|
||||
}
|
||||
|
||||
c = *output++ = (unsigned char)( iv[0] ^ *input++ );
|
||||
|
||||
if ( mode == ESP_AES_ENCRYPT ) {
|
||||
ov[16] = c;
|
||||
}
|
||||
|
||||
memcpy( iv, ov + 1, 16 );
|
||||
}
|
||||
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-CTR buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_ctr( esp_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int c, i;
|
||||
size_t n = *nc_off;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
while ( length-- ) {
|
||||
if ( n == 0 ) {
|
||||
esp_aes_block(ctx, nonce_counter, stream_block);
|
||||
|
||||
for ( i = 16; i > 0; i-- )
|
||||
if ( ++nonce_counter[i - 1] != 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = *input++;
|
||||
*output++ = (unsigned char)( c ^ stream_block[n] );
|
||||
|
||||
n = ( n + 1 ) & 0x0F;
|
||||
}
|
||||
|
||||
*nc_off = n;
|
||||
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-OFB (Output Feedback Mode) buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_ofb( esp_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t n;
|
||||
|
||||
if ( ctx == NULL || iv_off == NULL || iv == NULL ||
|
||||
input == NULL || output == NULL ) {
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
n = *iv_off;
|
||||
|
||||
if( n > 15 ) {
|
||||
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
while( length-- ) {
|
||||
if( n == 0 ) {
|
||||
esp_aes_block(ctx, iv, iv);
|
||||
}
|
||||
*output++ = *input++ ^ iv[n];
|
||||
|
||||
n = ( n + 1 ) & 0x0F;
|
||||
}
|
||||
|
||||
*iv_off = n;
|
||||
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Below XTS implementation is copied aes.c of mbedtls library.
|
||||
* When MBEDTLS_AES_ALT is defined mbedtls expects alternate
|
||||
* definition of XTS functions to be available. Even if this
|
||||
* could have been avoided, it is done for consistency reason.
|
||||
*/
|
||||
|
||||
void esp_aes_xts_init( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_init( &ctx->crypt );
|
||||
esp_aes_init( &ctx->tweak );
|
||||
}
|
||||
|
||||
void esp_aes_xts_free( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_free( &ctx->crypt );
|
||||
esp_aes_free( &ctx->tweak );
|
||||
}
|
||||
|
||||
static int esp_aes_xts_decode_keys( const unsigned char *key,
|
||||
unsigned int keybits,
|
||||
const unsigned char **key1,
|
||||
unsigned int *key1bits,
|
||||
const unsigned char **key2,
|
||||
unsigned int *key2bits )
|
||||
{
|
||||
const unsigned int half_keybits = keybits / 2;
|
||||
const unsigned int half_keybytes = half_keybits / 8;
|
||||
|
||||
switch( keybits )
|
||||
{
|
||||
case 256: break;
|
||||
case 512: break;
|
||||
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
|
||||
}
|
||||
|
||||
*key1bits = half_keybits;
|
||||
*key2bits = half_keybits;
|
||||
*key1 = &key[0];
|
||||
*key2 = &key[half_keybytes];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set the tweak key. Always set tweak key for the encryption mode. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for encryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set the tweak key. Always set tweak key for encryption. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for decryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
/* Endianess with 64 bits values */
|
||||
#ifndef GET_UINT64_LE
|
||||
#define GET_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) ] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT64_LE
|
||||
#define PUT_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) ] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef unsigned char esp_be128[16];
|
||||
|
||||
/*
|
||||
* GF(2^128) multiplication function
|
||||
*
|
||||
* This function multiplies a field element by x in the polynomial field
|
||||
* representation. It uses 64-bit word operations to gain speed but compensates
|
||||
* for machine endianess and hence works correctly on both big and little
|
||||
* endian machines.
|
||||
*/
|
||||
static void esp_gf128mul_x_ble( unsigned char r[16],
|
||||
const unsigned char x[16] )
|
||||
{
|
||||
uint64_t a, b, ra, rb;
|
||||
|
||||
GET_UINT64_LE( a, x, 0 );
|
||||
GET_UINT64_LE( b, x, 8 );
|
||||
|
||||
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
|
||||
rb = ( a >> 63 ) | ( b << 1 );
|
||||
|
||||
PUT_UINT64_LE( ra, r, 0 );
|
||||
PUT_UINT64_LE( rb, r, 8 );
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-XTS buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_xts( esp_aes_xts_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret;
|
||||
size_t blocks = length / 16;
|
||||
size_t leftover = length % 16;
|
||||
unsigned char tweak[16];
|
||||
unsigned char prev_tweak[16];
|
||||
unsigned char tmp[16];
|
||||
|
||||
/* Sectors must be at least 16 bytes. */
|
||||
if( length < 16 )
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
|
||||
/* NIST SP 80-38E disallows data units larger than 2**20 blocks. */
|
||||
if( length > ( 1 << 20 ) * 16 )
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
|
||||
/* Compute the tweak. */
|
||||
ret = esp_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
|
||||
data_unit, tweak );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
while( blocks-- )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
|
||||
{
|
||||
/* We are on the last block in a decrypt operation that has
|
||||
* leftover bytes, so we need to use the next tweak for this block,
|
||||
* and this tweak for the lefover bytes. Save the current tweak for
|
||||
* the leftovers and then update the current tweak for use on this,
|
||||
* the last full block. */
|
||||
memcpy( prev_tweak, tweak, sizeof( tweak ) );
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
tmp[i] = input[i] ^ tweak[i];
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
output[i] = tmp[i] ^ tweak[i];
|
||||
|
||||
/* Update the tweak for the next block. */
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
|
||||
output += 16;
|
||||
input += 16;
|
||||
}
|
||||
|
||||
if( leftover )
|
||||
{
|
||||
/* If we are on the leftover bytes in a decrypt operation, we need to
|
||||
* use the previous tweak for these bytes (as saved in prev_tweak). */
|
||||
unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
|
||||
|
||||
/* We are now on the final part of the data unit, which doesn't divide
|
||||
* evenly by 16. It's time for ciphertext stealing. */
|
||||
size_t i;
|
||||
unsigned char *prev_output = output - 16;
|
||||
|
||||
/* Copy ciphertext bytes from the previous block to our output for each
|
||||
* byte of cyphertext we won't steal. At the same time, copy the
|
||||
* remainder of the input for this final round (since the loop bounds
|
||||
* are the same). */
|
||||
for( i = 0; i < leftover; i++ )
|
||||
{
|
||||
output[i] = prev_output[i];
|
||||
tmp[i] = input[i] ^ t[i];
|
||||
}
|
||||
|
||||
/* Copy ciphertext bytes from the previous block for input in this
|
||||
* round. */
|
||||
for( ; i < 16; i++ )
|
||||
tmp[i] = prev_output[i] ^ t[i];
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if( ret != 0 )
|
||||
return ret;
|
||||
|
||||
/* Write the result back to the previous block, overriding the previous
|
||||
* output we copied. */
|
||||
for( i = 0; i < 16; i++ )
|
||||
prev_output[i] = tmp[i] ^ t[i];
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
314
components/mbedtls/port/esp32/sha.c
Normal file
314
components/mbedtls/port/esp32/sha.c
Normal file
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* ESP32 hardware accelerated SHA1/256/512 implementation
|
||||
* based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* The SHA-1 standard was published by NIST in 1993.
|
||||
*
|
||||
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <machine/endian.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "esp32/sha.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "soc/hwcrypto_periph.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_LOAD_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_BUSY_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
inline static uint32_t SHA_START_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_START_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_CONTINUE_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
/* Single spinlock for SHA engine memory block
|
||||
*/
|
||||
static portMUX_TYPE memory_block_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
|
||||
/* Binary semaphore managing the state of each concurrent SHA engine.
|
||||
|
||||
Available = noone is using this SHA engine
|
||||
Taken = a SHA session is running on this SHA engine
|
||||
|
||||
Indexes:
|
||||
0 = SHA1
|
||||
1 = SHA2_256
|
||||
2 = SHA2_384 or SHA2_512
|
||||
*/
|
||||
static SemaphoreHandle_t engine_states[3];
|
||||
|
||||
static uint8_t engines_in_use;
|
||||
|
||||
/* Spinlock for engines_in_use counter
|
||||
*/
|
||||
static portMUX_TYPE engines_in_use_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
/* Index into the engine_states array */
|
||||
inline static size_t sha_engine_index(esp_sha_type type) {
|
||||
switch(type) {
|
||||
case SHA1:
|
||||
return 0;
|
||||
case SHA2_256:
|
||||
return 1;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return digest length (in bytes) for a given SHA type */
|
||||
inline static size_t sha_length(esp_sha_type type) {
|
||||
switch(type) {
|
||||
case SHA1:
|
||||
return 20;
|
||||
case SHA2_256:
|
||||
return 32;
|
||||
case SHA2_384:
|
||||
return 48;
|
||||
case SHA2_512:
|
||||
return 64;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return block size (in bytes) for a given SHA type */
|
||||
inline static size_t block_length(esp_sha_type type) {
|
||||
switch(type) {
|
||||
case SHA1:
|
||||
case SHA2_256:
|
||||
return 64;
|
||||
case SHA2_384:
|
||||
case SHA2_512:
|
||||
return 128;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_sha_lock_memory_block(void)
|
||||
{
|
||||
portENTER_CRITICAL(&memory_block_lock);
|
||||
}
|
||||
|
||||
void esp_sha_unlock_memory_block(void)
|
||||
{
|
||||
portEXIT_CRITICAL(&memory_block_lock);
|
||||
}
|
||||
|
||||
static SemaphoreHandle_t sha_get_engine_state(esp_sha_type sha_type)
|
||||
{
|
||||
unsigned idx = sha_engine_index(sha_type);
|
||||
volatile SemaphoreHandle_t *engine = &engine_states[idx];
|
||||
SemaphoreHandle_t result = *engine;
|
||||
uint32_t set_engine = 0;
|
||||
|
||||
if (result == NULL) {
|
||||
// Create a new semaphore for 'in use' flag
|
||||
SemaphoreHandle_t new_engine = xSemaphoreCreateBinary();
|
||||
assert(new_engine != NULL);
|
||||
xSemaphoreGive(new_engine); // start available
|
||||
|
||||
// try to atomically set the previously NULL *engine to new_engine
|
||||
set_engine = (uint32_t)new_engine;
|
||||
uxPortCompareSet((volatile uint32_t *)engine, 0, &set_engine);
|
||||
|
||||
if (set_engine != 0) { // we lost a race setting *engine
|
||||
vSemaphoreDelete(new_engine);
|
||||
}
|
||||
result = *engine;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool esp_sha_lock_engine_common(esp_sha_type sha_type, TickType_t ticks_to_wait);
|
||||
|
||||
bool esp_sha_try_lock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
return esp_sha_lock_engine_common(sha_type, 0);
|
||||
}
|
||||
|
||||
void esp_sha_lock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
esp_sha_lock_engine_common(sha_type, portMAX_DELAY);
|
||||
}
|
||||
|
||||
static bool esp_sha_lock_engine_common(esp_sha_type sha_type, TickType_t ticks_to_wait)
|
||||
{
|
||||
SemaphoreHandle_t engine_state = sha_get_engine_state(sha_type);
|
||||
BaseType_t result = xSemaphoreTake(engine_state, ticks_to_wait);
|
||||
|
||||
if (result == pdFALSE) {
|
||||
// failed to take semaphore
|
||||
return false;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&engines_in_use_lock);
|
||||
|
||||
if (engines_in_use == 0) {
|
||||
/* Just locked first engine,
|
||||
so enable SHA hardware */
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
}
|
||||
|
||||
engines_in_use++;
|
||||
assert(engines_in_use <= 3);
|
||||
|
||||
portEXIT_CRITICAL(&engines_in_use_lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void esp_sha_unlock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type);
|
||||
|
||||
portENTER_CRITICAL(&engines_in_use_lock);
|
||||
|
||||
engines_in_use--;
|
||||
|
||||
if (engines_in_use == 0) {
|
||||
/* About to release last engine, so
|
||||
disable SHA hardware */
|
||||
periph_module_disable(PERIPH_SHA_MODULE);
|
||||
}
|
||||
|
||||
portEXIT_CRITICAL(&engines_in_use_lock);
|
||||
|
||||
xSemaphoreGive(engine_state);
|
||||
}
|
||||
|
||||
void esp_sha_wait_idle(void)
|
||||
{
|
||||
while(1) {
|
||||
if(DPORT_REG_READ(SHA_1_BUSY_REG) == 0
|
||||
&& DPORT_REG_READ(SHA_256_BUSY_REG) == 0
|
||||
&& DPORT_REG_READ(SHA_384_BUSY_REG) == 0
|
||||
&& DPORT_REG_READ(SHA_512_BUSY_REG) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
|
||||
{
|
||||
uint32_t *digest_state_words = NULL;
|
||||
uint32_t *reg_addr_buf = NULL;
|
||||
uint32_t word_len = sha_length(sha_type)/4;
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type);
|
||||
assert(uxSemaphoreGetCount(engine_state) == 0 &&
|
||||
"SHA engine should be locked" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// preemptively do this before entering the critical section, then re-check once in it
|
||||
esp_sha_wait_idle();
|
||||
|
||||
esp_sha_lock_memory_block();
|
||||
|
||||
esp_sha_wait_idle();
|
||||
|
||||
DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1);
|
||||
while(DPORT_REG_READ(SHA_BUSY_REG(sha_type)) == 1) { }
|
||||
digest_state_words = (uint32_t *)digest_state;
|
||||
reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||
if(sha_type == SHA2_384 || sha_type == SHA2_512) {
|
||||
/* for these ciphers using 64-bit states, swap each pair of words */
|
||||
DPORT_INTERRUPT_DISABLE(); // Disable interrupt only on current CPU.
|
||||
for(int i = 0; i < word_len; i += 2) {
|
||||
digest_state_words[i+1] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i]);
|
||||
digest_state_words[i] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i+1]);
|
||||
}
|
||||
DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level
|
||||
} else {
|
||||
esp_dport_access_read_buffer(digest_state_words, (uint32_t)®_addr_buf[0], word_len);
|
||||
}
|
||||
esp_sha_unlock_memory_block();
|
||||
|
||||
/* Fault injection check: verify SHA engine actually ran,
|
||||
state is not all zeroes.
|
||||
*/
|
||||
for (int i = 0; i < word_len; i++) {
|
||||
if (digest_state_words[i] != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
abort(); // SHA peripheral returned all zero state, probably due to fault injection
|
||||
}
|
||||
|
||||
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
|
||||
{
|
||||
uint32_t *reg_addr_buf = NULL;
|
||||
uint32_t *data_words = NULL;
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type);
|
||||
assert(uxSemaphoreGetCount(engine_state) == 0 &&
|
||||
"SHA engine should be locked" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// preemptively do this before entering the critical section, then re-check once in it
|
||||
esp_sha_wait_idle();
|
||||
|
||||
esp_sha_lock_memory_block();
|
||||
|
||||
esp_sha_wait_idle();
|
||||
|
||||
/* Fill the data block */
|
||||
reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||
data_words = (uint32_t *)data_block;
|
||||
for (int i = 0; i < block_length(sha_type) / 4; i++) {
|
||||
reg_addr_buf[i] = __builtin_bswap32(data_words[i]);
|
||||
}
|
||||
asm volatile ("memw");
|
||||
|
||||
if(is_first_block) {
|
||||
DPORT_REG_WRITE(SHA_START_REG(sha_type), 1);
|
||||
} else {
|
||||
DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
|
||||
}
|
||||
|
||||
esp_sha_unlock_memory_block();
|
||||
|
||||
/* Note: deliberately not waiting for this operation to complete,
|
||||
as a performance tweak - delay waiting until the next time we need the SHA
|
||||
unit, instead.
|
||||
*/
|
||||
}
|
683
components/mbedtls/port/esp_bignum.c
Normal file
683
components/mbedtls/port/esp_bignum.c
Normal file
@ -0,0 +1,683 @@
|
||||
/**
|
||||
* \brief Multi-precision integer library, ESP32 hardware accelerated parts
|
||||
*
|
||||
* based on mbedTLS implementation
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp32/rom/bigint.h"
|
||||
#include "soc/hwcrypto_periph.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include <mbedtls/bignum.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
/* Some implementation notes:
|
||||
*
|
||||
* - Naming convention x_words, y_words, z_words for number of words (limbs) used in a particular
|
||||
* bignum. This number may be less than the size of the bignum
|
||||
*
|
||||
* - Naming convention hw_words for the hardware length of the operation. This number is always
|
||||
* rounded up to a 512 bit multiple, and may be larger than any of the numbers involved in the
|
||||
* calculation.
|
||||
*
|
||||
* - Timing behaviour of these functions will depend on the length of the inputs. This is fundamentally
|
||||
* the same constraint as the software mbedTLS implementations, and relies on the same
|
||||
* countermeasures (exponent blinding, etc) which are used in mbedTLS.
|
||||
*/
|
||||
|
||||
static const __attribute__((unused)) char *TAG = "bignum";
|
||||
|
||||
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
|
||||
#define biL (ciL << 3) /* bits in limb */
|
||||
|
||||
#if defined(CONFIG_MBEDTLS_MPI_USE_INTERRUPT)
|
||||
static SemaphoreHandle_t op_complete_sem;
|
||||
|
||||
static IRAM_ATTR void rsa_complete_isr(void *arg)
|
||||
{
|
||||
BaseType_t higher_woken;
|
||||
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
|
||||
xSemaphoreGiveFromISR(op_complete_sem, &higher_woken);
|
||||
if (higher_woken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static void rsa_isr_initialise(void)
|
||||
{
|
||||
if (op_complete_sem == NULL) {
|
||||
op_complete_sem = xSemaphoreCreateBinary();
|
||||
esp_intr_alloc(ETS_RSA_INTR_SOURCE, 0, rsa_complete_isr, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MBEDTLS_MPI_USE_INTERRUPT */
|
||||
|
||||
static _lock_t mpi_lock;
|
||||
|
||||
void esp_mpi_acquire_hardware( void )
|
||||
{
|
||||
/* newlib locks lazy initialize on ESP-IDF */
|
||||
_lock_acquire(&mpi_lock);
|
||||
|
||||
/* Enable RSA hardware */
|
||||
periph_module_enable(PERIPH_RSA_MODULE);
|
||||
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
|
||||
while(DPORT_REG_READ(RSA_CLEAN_REG) != 1);
|
||||
// Note: from enabling RSA clock to here takes about 1.3us
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
|
||||
rsa_isr_initialise();
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_mpi_release_hardware( void )
|
||||
{
|
||||
DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
|
||||
/* Disable RSA hardware */
|
||||
periph_module_disable(PERIPH_RSA_MODULE);
|
||||
|
||||
_lock_release(&mpi_lock);
|
||||
}
|
||||
|
||||
/* Convert bit count to word count
|
||||
*/
|
||||
static inline size_t bits_to_words(size_t bits)
|
||||
{
|
||||
return (bits + 31) / 32;
|
||||
}
|
||||
|
||||
/* Round up number of words to nearest
|
||||
512 bit (16 word) block count.
|
||||
*/
|
||||
static inline size_t hardware_words(size_t words)
|
||||
{
|
||||
return (words + 0xF) & ~0xF;
|
||||
}
|
||||
|
||||
/* Number of words used to hold 'mpi'.
|
||||
|
||||
Equivalent of bits_to_words(mbedtls_mpi_bitlen(mpi)), but uses less cycles if the
|
||||
exact bit count is not needed.
|
||||
|
||||
Note that mpi->n (size of memory buffer) may be higher than this
|
||||
number, if the high bits are mostly zeroes.
|
||||
*/
|
||||
static inline size_t word_length(const mbedtls_mpi *mpi)
|
||||
{
|
||||
for(size_t i = mpi->n; i > 0; i--) {
|
||||
if( mpi->p[i - 1] != 0 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'.
|
||||
|
||||
If hw_words is higher than the number of words in the bignum then
|
||||
these additional words will be zeroed in the memory buffer.
|
||||
|
||||
*/
|
||||
static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t hw_words)
|
||||
{
|
||||
uint32_t *pbase = (uint32_t *)mem_base;
|
||||
uint32_t copy_words = hw_words < mpi->n ? hw_words : mpi->n;
|
||||
|
||||
/* Copy MPI data to memory block registers */
|
||||
for (int i = 0; i < copy_words; i++) {
|
||||
pbase[i] = mpi->p[i];
|
||||
}
|
||||
|
||||
/* Zero any remaining memory block data */
|
||||
for (int i = copy_words; i < hw_words; i++) {
|
||||
pbase[i] = 0;
|
||||
}
|
||||
|
||||
/* Note: not executing memw here, can do it before we start a bignum operation */
|
||||
}
|
||||
|
||||
/* Read mbedTLS MPI bignum back from hardware memory block.
|
||||
|
||||
Reads num_words words from block.
|
||||
|
||||
Bignum 'x' should already be grown to at least num_words by caller (can be done while
|
||||
calculation is in progress, to save some cycles)
|
||||
*/
|
||||
static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words)
|
||||
{
|
||||
assert(x->n >= num_words);
|
||||
|
||||
/* Copy data from memory block registers */
|
||||
esp_dport_access_read_buffer(x->p, mem_base, num_words);
|
||||
|
||||
/* Zero any remaining limbs in the bignum, if the buffer is bigger
|
||||
than num_words */
|
||||
for(size_t i = num_words; i < x->n; i++) {
|
||||
x->p[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1,
|
||||
* where B^-1(B-1) mod N=1. Actually, only the least significant part of
|
||||
* N' is needed, hence the definition N0'=N' mod b. We reproduce below the
|
||||
* simple algorithm from an article by Dusse and Kaliski to efficiently
|
||||
* find N0' from N0 and b
|
||||
*/
|
||||
static mbedtls_mpi_uint modular_inverse(const mbedtls_mpi *M)
|
||||
{
|
||||
int i;
|
||||
uint64_t t = 1;
|
||||
uint64_t two_2_i_minus_1 = 2; /* 2^(i-1) */
|
||||
uint64_t two_2_i = 4; /* 2^i */
|
||||
uint64_t N = M->p[0];
|
||||
|
||||
for (i = 2; i <= 32; i++) {
|
||||
if ((mbedtls_mpi_uint) N * t % two_2_i >= two_2_i_minus_1) {
|
||||
t += two_2_i_minus_1;
|
||||
}
|
||||
|
||||
two_2_i_minus_1 <<= 1;
|
||||
two_2_i <<= 1;
|
||||
}
|
||||
|
||||
return (mbedtls_mpi_uint)(UINT32_MAX - t + 1);
|
||||
}
|
||||
|
||||
/* Calculate Rinv = RR^2 mod M, where:
|
||||
*
|
||||
* R = b^n where b = 2^32, n=num_words,
|
||||
* R = 2^N (where N=num_bits)
|
||||
* RR = R^2 = 2^(2*N) (where N=num_bits=num_words*32)
|
||||
*
|
||||
* This calculation is computationally expensive (mbedtls_mpi_mod_mpi)
|
||||
* so caller should cache the result where possible.
|
||||
*
|
||||
* DO NOT call this function while holding esp_mpi_acquire_hardware().
|
||||
*
|
||||
*/
|
||||
static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words)
|
||||
{
|
||||
int ret;
|
||||
size_t num_bits = num_words * 32;
|
||||
mbedtls_mpi RR;
|
||||
mbedtls_mpi_init(&RR);
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&RR, num_bits * 2, 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(Rinv, &RR, M));
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&RR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Begin an RSA operation. op_reg specifies which 'START' register
|
||||
to write to.
|
||||
*/
|
||||
static inline void start_op(uint32_t op_reg)
|
||||
{
|
||||
/* Clear interrupt status */
|
||||
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
|
||||
|
||||
/* Note: above REG_WRITE includes a memw, so we know any writes
|
||||
to the memory blocks are also complete. */
|
||||
|
||||
DPORT_REG_WRITE(op_reg, 1);
|
||||
}
|
||||
|
||||
/* Wait for an RSA operation to complete.
|
||||
*/
|
||||
static inline void wait_op_complete(uint32_t op_reg)
|
||||
{
|
||||
#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
|
||||
if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) {
|
||||
ESP_LOGE(TAG, "Timed out waiting for RSA operation (op_reg 0x%x int_reg 0x%x)",
|
||||
op_reg, DPORT_REG_READ(RSA_INTERRUPT_REG));
|
||||
abort(); /* indicates a fundamental problem with driver */
|
||||
}
|
||||
#else
|
||||
while(DPORT_REG_READ(RSA_INTERRUPT_REG) != 1)
|
||||
{ }
|
||||
|
||||
/* clear the interrupt */
|
||||
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Sub-stages of modulo multiplication/exponentiation operations */
|
||||
inline static int modular_multiply_finish(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t hw_words, size_t z_words);
|
||||
|
||||
/* Z = (X * Y) mod M
|
||||
|
||||
Not an mbedTLS function
|
||||
*/
|
||||
int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M)
|
||||
{
|
||||
int ret;
|
||||
size_t x_bits = mbedtls_mpi_bitlen(X);
|
||||
size_t y_bits = mbedtls_mpi_bitlen(Y);
|
||||
size_t m_bits = mbedtls_mpi_bitlen(M);
|
||||
size_t z_bits = MIN(m_bits, x_bits + y_bits);
|
||||
size_t x_words = bits_to_words(x_bits);
|
||||
size_t y_words = bits_to_words(y_bits);
|
||||
size_t m_words = bits_to_words(m_bits);
|
||||
size_t z_words = bits_to_words(z_bits);
|
||||
size_t hw_words = hardware_words(MAX(x_words, MAX(y_words, m_words))); /* longest operand */
|
||||
mbedtls_mpi Rinv;
|
||||
mbedtls_mpi_uint Mprime;
|
||||
|
||||
/* Calculate and load the first stage montgomery multiplication */
|
||||
mbedtls_mpi_init(&Rinv);
|
||||
MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, hw_words));
|
||||
Mprime = modular_inverse(M);
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
/* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */
|
||||
mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, hw_words);
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words);
|
||||
mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, &Rinv, hw_words);
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, (uint32_t)Mprime);
|
||||
|
||||
/* "mode" register loaded with number of 512-bit blocks, minus 1 */
|
||||
DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hw_words / 16) - 1);
|
||||
|
||||
/* Execute first stage montgomery multiplication */
|
||||
start_op(RSA_MULT_START_REG);
|
||||
|
||||
wait_op_complete(RSA_MULT_START_REG);
|
||||
|
||||
/* execute second stage */
|
||||
ret = modular_multiply_finish(Z, X, Y, hw_words, z_words);
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&Rinv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_MPI_EXP_MOD_ALT)
|
||||
|
||||
/*
|
||||
* Sliding-window exponentiation: Z = X^Y mod M (HAC 14.85)
|
||||
*
|
||||
* _Rinv is optional pre-calculated version of Rinv (via calculate_rinv()).
|
||||
*
|
||||
* (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv)
|
||||
*
|
||||
*/
|
||||
int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi* Y, const mbedtls_mpi* M, mbedtls_mpi* _Rinv )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t x_words = word_length(X);
|
||||
size_t y_words = word_length(Y);
|
||||
size_t m_words = word_length(M);
|
||||
|
||||
/* "all numbers must be the same length", so choose longest number
|
||||
as cardinal length of operation...
|
||||
*/
|
||||
size_t hw_words = hardware_words(MAX(m_words, MAX(x_words, y_words)));
|
||||
|
||||
mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */
|
||||
mbedtls_mpi *Rinv; /* points to _Rinv (if not NULL) othwerwise &RR_new */
|
||||
mbedtls_mpi_uint Mprime;
|
||||
|
||||
if (mbedtls_mpi_cmp_int(M, 0) <= 0 || (M->p[0] & 1) == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (mbedtls_mpi_cmp_int(Y, 0) < 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (mbedtls_mpi_cmp_int(Y, 0) == 0) {
|
||||
return mbedtls_mpi_lset(Z, 1);
|
||||
}
|
||||
|
||||
if (hw_words * 32 > 4096) {
|
||||
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
}
|
||||
|
||||
/* Determine RR pointer, either _RR for cached value
|
||||
or local RR_new */
|
||||
if (_Rinv == NULL) {
|
||||
mbedtls_mpi_init(&Rinv_new);
|
||||
Rinv = &Rinv_new;
|
||||
} else {
|
||||
Rinv = _Rinv;
|
||||
}
|
||||
if (Rinv->p == NULL) {
|
||||
MBEDTLS_MPI_CHK(calculate_rinv(Rinv, M, hw_words));
|
||||
}
|
||||
|
||||
Mprime = modular_inverse(M);
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
/* "mode" register loaded with number of 512-bit blocks, minus 1 */
|
||||
DPORT_REG_WRITE(RSA_MODEXP_MODE_REG, (hw_words / 16) - 1);
|
||||
|
||||
/* Load M, X, Rinv, M-prime (M-prime is mod 2^32) */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words);
|
||||
mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, hw_words);
|
||||
mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, hw_words);
|
||||
mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, hw_words);
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime);
|
||||
|
||||
start_op(RSA_START_MODEXP_REG);
|
||||
|
||||
/* X ^ Y may actually be shorter than M, but unlikely when used for crypto */
|
||||
if ((ret = mbedtls_mpi_grow(Z, m_words)) != 0) {
|
||||
esp_mpi_release_hardware();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
wait_op_complete(RSA_START_MODEXP_REG);
|
||||
|
||||
mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words);
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
// Compensate for negative X
|
||||
if (X->s == -1 && (Y->p[0] & 1) != 0) {
|
||||
Z->s = -1;
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(Z, M, Z));
|
||||
} else {
|
||||
Z->s = 1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (_Rinv == NULL) {
|
||||
mbedtls_mpi_free(&Rinv_new);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_MPI_EXP_MOD_ALT */
|
||||
|
||||
/* Second & final step of a modular multiply - load second multiplication
|
||||
* factor Y, run the operation (modular inverse), read back the result
|
||||
* into Z.
|
||||
*
|
||||
* Called from both mbedtls_mpi_exp_mod and mbedtls_mpi_mod_mpi.
|
||||
*
|
||||
* @param Z result value
|
||||
* @param X first multiplication factor (used to set sign of result).
|
||||
* @param Y second multiplication factor.
|
||||
* @param hw_words Size of the hardware operation, in words
|
||||
* @param z_words Size of the expected result, in words (may be less than hw_words).
|
||||
* Z will be grown to at least this length.
|
||||
*
|
||||
* Caller must have already called esp_mpi_acquire_hardware().
|
||||
*/
|
||||
static int modular_multiply_finish(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t hw_words, size_t z_words)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Load Y to X input memory block, rerun */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, Y, hw_words);
|
||||
|
||||
start_op(RSA_MULT_START_REG);
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, z_words) );
|
||||
|
||||
wait_op_complete(RSA_MULT_START_REG);
|
||||
|
||||
mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words);
|
||||
|
||||
Z->s = X->s * Y->s;
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */
|
||||
|
||||
static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t z_words);
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t Y_bits, size_t z_words);
|
||||
|
||||
/* Z = X * Y */
|
||||
int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t x_bits = mbedtls_mpi_bitlen(X);
|
||||
size_t y_bits = mbedtls_mpi_bitlen(Y);
|
||||
size_t x_words = bits_to_words(x_bits);
|
||||
size_t y_words = bits_to_words(y_bits);
|
||||
size_t z_words = bits_to_words(x_bits + y_bits);
|
||||
size_t hw_words = hardware_words(MAX(x_words, y_words)); // length of one operand in hardware
|
||||
|
||||
/* Short-circuit eval if either argument is 0 or 1.
|
||||
|
||||
This is needed as the mpi modular division
|
||||
argument will sometimes call in here when one
|
||||
argument is too large for the hardware unit, but the other
|
||||
argument is zero or one.
|
||||
*/
|
||||
if (x_bits == 0 || y_bits == 0) {
|
||||
mbedtls_mpi_lset(Z, 0);
|
||||
return 0;
|
||||
}
|
||||
if (x_bits == 1) {
|
||||
ret = mbedtls_mpi_copy(Z, Y);
|
||||
Z->s *= X->s;
|
||||
return ret;
|
||||
}
|
||||
if (y_bits == 1) {
|
||||
ret = mbedtls_mpi_copy(Z, X);
|
||||
Z->s *= Y->s;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If either factor is over 2048 bits, we can't use the standard hardware multiplier
|
||||
(it assumes result is double longest factor, and result is max 4096 bits.)
|
||||
|
||||
However, we can fail over to mod_mult for up to 4096 bits of result (modulo
|
||||
multiplication doesn't have the same restriction, so result is simply the
|
||||
number of bits in X plus number of bits in in Y.)
|
||||
*/
|
||||
if (hw_words * 32 > 2048) {
|
||||
if (z_words * 32 <= 4096) {
|
||||
/* Note: it's possible to use mpi_mult_mpi_overlong
|
||||
for this case as well, but it's very slightly
|
||||
slower and requires a memory allocation.
|
||||
*/
|
||||
return mpi_mult_mpi_failover_mod_mult(Z, X, Y, z_words);
|
||||
} else {
|
||||
/* Still too long for the hardware unit... */
|
||||
if(y_words > x_words) {
|
||||
return mpi_mult_mpi_overlong(Z, X, Y, y_words, z_words);
|
||||
} else {
|
||||
return mpi_mult_mpi_overlong(Z, Y, X, x_words, z_words);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we can use the (faster) multiply hardware unit */
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
/* Copy X (right-extended) & Y (left-extended) to memory block */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words);
|
||||
mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + hw_words * 4, Y, hw_words);
|
||||
/* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block.
|
||||
This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware().
|
||||
*/
|
||||
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, 0);
|
||||
|
||||
/* "mode" register loaded with number of 512-bit blocks in result,
|
||||
plus 7 (for range 9-12). (this is ((N~ / 32) - 1) + 8))
|
||||
*/
|
||||
DPORT_REG_WRITE(RSA_MULT_MODE_REG, ((hw_words * 2) / 16) + 7);
|
||||
|
||||
start_op(RSA_MULT_START_REG);
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, z_words) );
|
||||
|
||||
wait_op_complete(RSA_MULT_START_REG);
|
||||
|
||||
/* Read back the result */
|
||||
mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words);
|
||||
|
||||
Z->s = X->s * Y->s;
|
||||
|
||||
cleanup:
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Special-case of mbedtls_mpi_mult_mpi(), where we use hardware montgomery mod
|
||||
multiplication to calculate an mbedtls_mpi_mult_mpi result where either
|
||||
A or B are >2048 bits so can't use the standard multiplication method.
|
||||
|
||||
Result (z_words, based on A bits + B bits) must still be less than 4096 bits.
|
||||
|
||||
This case is simpler than the general case modulo multiply of
|
||||
esp_mpi_mul_mpi_mod() because we can control the other arguments:
|
||||
|
||||
* Modulus is chosen with M=(2^num_bits - 1) (ie M=R-1), so output
|
||||
isn't actually modulo anything.
|
||||
* Mprime and Rinv are therefore predictable as follows:
|
||||
Mprime = 1
|
||||
Rinv = 1
|
||||
|
||||
(See RSA Accelerator section in Technical Reference for more about Mprime, Rinv)
|
||||
*/
|
||||
static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t z_words)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t hw_words = hardware_words(z_words);
|
||||
|
||||
/* Load coefficients to hardware */
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
/* M = 2^num_words - 1, so block is entirely FF */
|
||||
for(int i = 0; i < hw_words; i++) {
|
||||
DPORT_REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX);
|
||||
}
|
||||
/* Mprime = 1 */
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, 1);
|
||||
|
||||
/* "mode" register loaded with number of 512-bit blocks, minus 1 */
|
||||
DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hw_words / 16) - 1);
|
||||
|
||||
/* Load X */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words);
|
||||
|
||||
/* Rinv = 1 */
|
||||
DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1);
|
||||
for(int i = 1; i < hw_words; i++) {
|
||||
DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0);
|
||||
}
|
||||
|
||||
start_op(RSA_MULT_START_REG);
|
||||
|
||||
wait_op_complete(RSA_MULT_START_REG);
|
||||
|
||||
/* finish the modular multiplication */
|
||||
ret = modular_multiply_finish(Z, X, Y, hw_words, z_words);
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Deal with the case when X & Y are too long for the hardware unit, by splitting one operand
|
||||
into two halves.
|
||||
|
||||
Y must be the longer operand
|
||||
|
||||
Slice Y into Yp, Ypp such that:
|
||||
Yp = lower 'b' bits of Y
|
||||
Ypp = upper 'b' bits of Y (right shifted)
|
||||
|
||||
Such that
|
||||
Z = X * Y
|
||||
Z = X * (Yp + Ypp<<b)
|
||||
Z = (X * Yp) + (X * Ypp<<b)
|
||||
|
||||
Note that this function may recurse multiple times, if both X & Y
|
||||
are too long for the hardware multiplication unit.
|
||||
*/
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t y_words, size_t z_words)
|
||||
{
|
||||
int ret = 0;
|
||||
mbedtls_mpi Ztemp;
|
||||
/* Rather than slicing in two on bits we slice on limbs (32 bit words) */
|
||||
const size_t words_slice = y_words / 2;
|
||||
/* Yp holds lower bits of Y (declared to reuse Y's array contents to save on copying) */
|
||||
const mbedtls_mpi Yp = {
|
||||
.p = Y->p,
|
||||
.n = words_slice,
|
||||
.s = Y->s
|
||||
};
|
||||
/* Ypp holds upper bits of Y, right shifted (also reuses Y's array contents) */
|
||||
const mbedtls_mpi Ypp = {
|
||||
.p = Y->p + words_slice,
|
||||
.n = y_words - words_slice,
|
||||
.s = Y->s
|
||||
};
|
||||
mbedtls_mpi_init(&Ztemp);
|
||||
|
||||
/* Grow Z to result size early, avoid interim allocations */
|
||||
mbedtls_mpi_grow(Z, z_words);
|
||||
|
||||
/* Get result Ztemp = Yp * X (need temporary variable Ztemp) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(&Ztemp, X, &Yp) );
|
||||
|
||||
/* Z = Ypp * Y */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(Z, X, &Ypp) );
|
||||
|
||||
/* Z = Z << b */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(Z, words_slice * 32) );
|
||||
|
||||
/* Z += Ztemp */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(Z, Z, &Ztemp) );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&Ztemp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_MPI_MUL_MPI_ALT */
|
||||
|
26
components/mbedtls/port/esp_hardware.c
Normal file
26
components/mbedtls/port/esp_hardware.c
Normal file
@ -0,0 +1,26 @@
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <esp_system.h>
|
||||
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
|
||||
#ifndef MBEDTLS_ENTROPY_HARDWARE_ALT
|
||||
#error "MBEDTLS_ENTROPY_HARDWARE_ALT should always be set in ESP-IDF"
|
||||
#endif
|
||||
|
||||
int mbedtls_hardware_poll( void *data,
|
||||
unsigned char *output, size_t len, size_t *olen )
|
||||
{
|
||||
esp_fill_random(output, len);
|
||||
*olen = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
38
components/mbedtls/port/esp_mem.c
Normal file
38
components/mbedtls/port/esp_mem.c
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <esp_attr.h>
|
||||
#include <esp_heap_caps.h>
|
||||
#include <sdkconfig.h>
|
||||
#include "esp_mem.h"
|
||||
|
||||
#ifndef CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
|
||||
IRAM_ATTR void *esp_mbedtls_mem_calloc(size_t n, size_t size)
|
||||
{
|
||||
#ifdef CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC
|
||||
return heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC
|
||||
return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
|
||||
#else
|
||||
return calloc(n, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
IRAM_ATTR void esp_mbedtls_mem_free(void *ptr)
|
||||
{
|
||||
return heap_caps_free(ptr);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC */
|
79
components/mbedtls/port/esp_sha.c
Normal file
79
components/mbedtls/port/esp_sha.c
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "esp32/sha.h"
|
||||
#include <mbedtls/sha1.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/sha512.h>
|
||||
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
|
||||
{
|
||||
int ret;
|
||||
assert(input != NULL && output != NULL);
|
||||
|
||||
if (sha_type == SHA1) {
|
||||
|
||||
mbedtls_sha1_context *ctx1 = (mbedtls_sha1_context *)malloc(sizeof(mbedtls_sha1_context));
|
||||
assert(ctx1 != NULL);
|
||||
mbedtls_sha1_starts_ret(ctx1);
|
||||
ret = mbedtls_sha1_update_ret(ctx1, input, ilen);
|
||||
assert(ret == 0);
|
||||
ret = mbedtls_sha1_finish_ret(ctx1, output);
|
||||
assert(ret == 0);
|
||||
mbedtls_sha1_free(ctx1);
|
||||
free(ctx1);
|
||||
|
||||
} else if (sha_type == SHA2_256) {
|
||||
|
||||
mbedtls_sha256_context *ctx256 = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
|
||||
assert(ctx256 != NULL);
|
||||
mbedtls_sha256_starts_ret(ctx256, 0);
|
||||
ret = mbedtls_sha256_update_ret(ctx256, input, ilen);
|
||||
assert(ret == 0);
|
||||
ret = mbedtls_sha256_finish_ret(ctx256, output);
|
||||
assert(ret == 0);
|
||||
mbedtls_sha256_free(ctx256);
|
||||
free(ctx256);
|
||||
|
||||
} else if (sha_type == SHA2_384) {
|
||||
|
||||
mbedtls_sha512_context *ctx384 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
|
||||
assert(ctx384 != NULL);
|
||||
mbedtls_sha512_starts_ret(ctx384, 1);
|
||||
ret = mbedtls_sha512_update_ret(ctx384, input, ilen);
|
||||
assert(ret == 0);
|
||||
ret = mbedtls_sha512_finish_ret(ctx384, output);
|
||||
assert(ret == 0);
|
||||
mbedtls_sha512_free(ctx384);
|
||||
free(ctx384);
|
||||
|
||||
} else if (sha_type == SHA2_512) {
|
||||
|
||||
mbedtls_sha512_context *ctx512 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
|
||||
assert(ctx512 != NULL);
|
||||
mbedtls_sha512_starts_ret(ctx512, 0);
|
||||
ret = mbedtls_sha512_update_ret(ctx512, input, ilen);
|
||||
assert(ret == 0);
|
||||
ret = mbedtls_sha512_finish_ret(ctx512, output);
|
||||
assert(ret == 0);
|
||||
mbedtls_sha512_free(ctx512);
|
||||
free(ctx512);
|
||||
|
||||
}
|
||||
|
||||
}
|
451
components/mbedtls/port/esp_sha1.c
Normal file
451
components/mbedtls/port/esp_sha1.c
Normal file
@ -0,0 +1,451 @@
|
||||
/*
|
||||
* SHA-1 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* The SHA-1 standard was published by NIST in 1993.
|
||||
*
|
||||
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
#include "mbedtls/sha1.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "esp32/sha.h"
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA1);
|
||||
}
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
|
||||
if (src->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
/* Copy hardware digest state out to cloned state,
|
||||
which will be a software digest.
|
||||
*/
|
||||
esp_sha_read_digest_state(SHA1, dst->state);
|
||||
dst->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA1);
|
||||
}
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_UNUSED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
mbedtls_sha1_starts_ret( ctx );
|
||||
}
|
||||
#endif
|
||||
|
||||
static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
|
||||
|
||||
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
bool first_block = false;
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_UNUSED) {
|
||||
/* try to use hardware for this digest */
|
||||
if (esp_sha_try_lock_engine(SHA1)) {
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_HARDWARE;
|
||||
first_block = true;
|
||||
} else {
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_block(SHA1, data, first_block);
|
||||
} else {
|
||||
mbedtls_sha1_software_process(ctx, data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
|
||||
const unsigned char data[64] )
|
||||
{
|
||||
mbedtls_internal_sha1_process( ctx, data );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
|
||||
GET_UINT32_BE( W[ 0], data, 0 );
|
||||
GET_UINT32_BE( W[ 1], data, 4 );
|
||||
GET_UINT32_BE( W[ 2], data, 8 );
|
||||
GET_UINT32_BE( W[ 3], data, 12 );
|
||||
GET_UINT32_BE( W[ 4], data, 16 );
|
||||
GET_UINT32_BE( W[ 5], data, 20 );
|
||||
GET_UINT32_BE( W[ 6], data, 24 );
|
||||
GET_UINT32_BE( W[ 7], data, 28 );
|
||||
GET_UINT32_BE( W[ 8], data, 32 );
|
||||
GET_UINT32_BE( W[ 9], data, 36 );
|
||||
GET_UINT32_BE( W[10], data, 40 );
|
||||
GET_UINT32_BE( W[11], data, 44 );
|
||||
GET_UINT32_BE( W[12], data, 48 );
|
||||
GET_UINT32_BE( W[13], data, 52 );
|
||||
GET_UINT32_BE( W[14], data, 56 );
|
||||
GET_UINT32_BE( W[15], data, 60 );
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
|
||||
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
|
||||
( W[t & 0x0F] = S(temp,1) ) \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,x) \
|
||||
{ \
|
||||
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define K 0x5A827999
|
||||
|
||||
P( A, B, C, D, E, W[0] );
|
||||
P( E, A, B, C, D, W[1] );
|
||||
P( D, E, A, B, C, W[2] );
|
||||
P( C, D, E, A, B, W[3] );
|
||||
P( B, C, D, E, A, W[4] );
|
||||
P( A, B, C, D, E, W[5] );
|
||||
P( E, A, B, C, D, W[6] );
|
||||
P( D, E, A, B, C, W[7] );
|
||||
P( C, D, E, A, B, W[8] );
|
||||
P( B, C, D, E, A, W[9] );
|
||||
P( A, B, C, D, E, W[10] );
|
||||
P( E, A, B, C, D, W[11] );
|
||||
P( D, E, A, B, C, W[12] );
|
||||
P( C, D, E, A, B, W[13] );
|
||||
P( B, C, D, E, A, W[14] );
|
||||
P( A, B, C, D, E, W[15] );
|
||||
P( E, A, B, C, D, R(16) );
|
||||
P( D, E, A, B, C, R(17) );
|
||||
P( C, D, E, A, B, R(18) );
|
||||
P( B, C, D, E, A, R(19) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0x6ED9EBA1
|
||||
|
||||
P( A, B, C, D, E, R(20) );
|
||||
P( E, A, B, C, D, R(21) );
|
||||
P( D, E, A, B, C, R(22) );
|
||||
P( C, D, E, A, B, R(23) );
|
||||
P( B, C, D, E, A, R(24) );
|
||||
P( A, B, C, D, E, R(25) );
|
||||
P( E, A, B, C, D, R(26) );
|
||||
P( D, E, A, B, C, R(27) );
|
||||
P( C, D, E, A, B, R(28) );
|
||||
P( B, C, D, E, A, R(29) );
|
||||
P( A, B, C, D, E, R(30) );
|
||||
P( E, A, B, C, D, R(31) );
|
||||
P( D, E, A, B, C, R(32) );
|
||||
P( C, D, E, A, B, R(33) );
|
||||
P( B, C, D, E, A, R(34) );
|
||||
P( A, B, C, D, E, R(35) );
|
||||
P( E, A, B, C, D, R(36) );
|
||||
P( D, E, A, B, C, R(37) );
|
||||
P( C, D, E, A, B, R(38) );
|
||||
P( B, C, D, E, A, R(39) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define K 0x8F1BBCDC
|
||||
|
||||
P( A, B, C, D, E, R(40) );
|
||||
P( E, A, B, C, D, R(41) );
|
||||
P( D, E, A, B, C, R(42) );
|
||||
P( C, D, E, A, B, R(43) );
|
||||
P( B, C, D, E, A, R(44) );
|
||||
P( A, B, C, D, E, R(45) );
|
||||
P( E, A, B, C, D, R(46) );
|
||||
P( D, E, A, B, C, R(47) );
|
||||
P( C, D, E, A, B, R(48) );
|
||||
P( B, C, D, E, A, R(49) );
|
||||
P( A, B, C, D, E, R(50) );
|
||||
P( E, A, B, C, D, R(51) );
|
||||
P( D, E, A, B, C, R(52) );
|
||||
P( C, D, E, A, B, R(53) );
|
||||
P( B, C, D, E, A, R(54) );
|
||||
P( A, B, C, D, E, R(55) );
|
||||
P( E, A, B, C, D, R(56) );
|
||||
P( D, E, A, B, C, R(57) );
|
||||
P( C, D, E, A, B, R(58) );
|
||||
P( B, C, D, E, A, R(59) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0xCA62C1D6
|
||||
|
||||
P( A, B, C, D, E, R(60) );
|
||||
P( E, A, B, C, D, R(61) );
|
||||
P( D, E, A, B, C, R(62) );
|
||||
P( C, D, E, A, B, R(63) );
|
||||
P( B, C, D, E, A, R(64) );
|
||||
P( A, B, C, D, E, R(65) );
|
||||
P( E, A, B, C, D, R(66) );
|
||||
P( D, E, A, B, C, R(67) );
|
||||
P( C, D, E, A, B, R(68) );
|
||||
P( B, C, D, E, A, R(69) );
|
||||
P( A, B, C, D, E, R(70) );
|
||||
P( E, A, B, C, D, R(71) );
|
||||
P( D, E, A, B, C, R(72) );
|
||||
P( C, D, E, A, B, R(73) );
|
||||
P( B, C, D, E, A, R(74) );
|
||||
P( A, B, C, D, E, R(75) );
|
||||
P( E, A, B, C, D, R(76) );
|
||||
P( D, E, A, B, C, R(77) );
|
||||
P( C, D, E, A, B, R(78) );
|
||||
P( B, C, D, E, A, R(79) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
int ret;
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen == 0 )
|
||||
return 0;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
|
||||
if ( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
if ( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
mbedtls_sha1_update_ret( ctx, input, ilen );
|
||||
}
|
||||
#endif
|
||||
|
||||
static const unsigned char sha1_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] )
|
||||
{
|
||||
int ret;
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
if ( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 ) {
|
||||
goto out;
|
||||
}
|
||||
if ( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 ) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* if state is in hardware, read it out */
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_read_digest_state(SHA1, ctx->state);
|
||||
}
|
||||
|
||||
PUT_UINT32_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_BE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_BE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_BE( ctx->state[3], output, 12 );
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
|
||||
out:
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA1);
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
|
||||
unsigned char output[20] )
|
||||
{
|
||||
mbedtls_sha1_finish_ret( ctx, output );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */
|
422
components/mbedtls/port/esp_sha256.c
Normal file
422
components/mbedtls/port/esp_sha256.c
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
* SHA-256 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "esp32/sha.h"
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
do { \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
} while( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
do { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
} while( 0 )
|
||||
#endif
|
||||
|
||||
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA2_256);
|
||||
}
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
|
||||
if (src->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
/* Copy hardware digest state out to cloned state,
|
||||
which will become a software digest.
|
||||
*/
|
||||
esp_sha_read_digest_state(SHA2_256, dst->state);
|
||||
dst->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 context setup
|
||||
*/
|
||||
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if( is224 == 0 )
|
||||
{
|
||||
/* SHA-256 */
|
||||
ctx->state[0] = 0x6A09E667;
|
||||
ctx->state[1] = 0xBB67AE85;
|
||||
ctx->state[2] = 0x3C6EF372;
|
||||
ctx->state[3] = 0xA54FF53A;
|
||||
ctx->state[4] = 0x510E527F;
|
||||
ctx->state[5] = 0x9B05688C;
|
||||
ctx->state[6] = 0x1F83D9AB;
|
||||
ctx->state[7] = 0x5BE0CD19;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHA-224 */
|
||||
ctx->state[0] = 0xC1059ED8;
|
||||
ctx->state[1] = 0x367CD507;
|
||||
ctx->state[2] = 0x3070DD17;
|
||||
ctx->state[3] = 0xF70E5939;
|
||||
ctx->state[4] = 0xFFC00B31;
|
||||
ctx->state[5] = 0x68581511;
|
||||
ctx->state[6] = 0x64F98FA7;
|
||||
ctx->state[7] = 0xBEFA4FA4;
|
||||
}
|
||||
|
||||
ctx->is224 = is224;
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA2_256);
|
||||
}
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_UNUSED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
|
||||
int is224 )
|
||||
{
|
||||
mbedtls_sha256_starts_ret( ctx, is224 );
|
||||
}
|
||||
#endif
|
||||
|
||||
static const uint32_t K[] =
|
||||
{
|
||||
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||||
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
||||
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
||||
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
||||
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
||||
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
||||
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
||||
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
||||
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
||||
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
||||
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
||||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
|
||||
};
|
||||
|
||||
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
|
||||
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
|
||||
|
||||
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
|
||||
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||||
S0(W[t - 15]) + W[t - 16] \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
|
||||
|
||||
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
bool first_block = false;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_UNUSED) {
|
||||
/* try to use hardware for this digest */
|
||||
if (!ctx->is224 && esp_sha_try_lock_engine(SHA2_256)) {
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_HARDWARE;
|
||||
first_block = true;
|
||||
} else {
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_block(SHA2_256, data, first_block);
|
||||
} else {
|
||||
mbedtls_sha256_software_process(ctx, data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
|
||||
const unsigned char data[64] )
|
||||
{
|
||||
mbedtls_internal_sha256_process( ctx, data );
|
||||
}
|
||||
#endif
|
||||
|
||||
static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t temp1, temp2, W[64];
|
||||
uint32_t A[8];
|
||||
unsigned int i;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
A[i] = ctx->state[i];
|
||||
|
||||
#if defined(MBEDTLS_SHA256_SMALLER)
|
||||
for( i = 0; i < 64; i++ )
|
||||
{
|
||||
if( i < 16 )
|
||||
GET_UINT32_BE( W[i], data, 4 * i );
|
||||
else
|
||||
R( i );
|
||||
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
|
||||
|
||||
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
|
||||
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
|
||||
}
|
||||
#else /* MBEDTLS_SHA256_SMALLER */
|
||||
for( i = 0; i < 16; i++ )
|
||||
GET_UINT32_BE( W[i], data, 4 * i );
|
||||
|
||||
for( i = 0; i < 16; i += 8 )
|
||||
{
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
|
||||
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
|
||||
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
|
||||
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
|
||||
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
|
||||
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
|
||||
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
|
||||
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
|
||||
}
|
||||
|
||||
for( i = 16; i < 64; i += 8 )
|
||||
{
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
|
||||
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
|
||||
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
|
||||
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
|
||||
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
|
||||
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
|
||||
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
|
||||
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
|
||||
}
|
||||
#endif /* MBEDTLS_SHA256_SMALLER */
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
ctx->state[i] += A[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 process buffer
|
||||
*/
|
||||
int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
int ret;
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen == 0 )
|
||||
return 0;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
|
||||
if ( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
if ( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
mbedtls_sha256_update_ret( ctx, input, ilen );
|
||||
}
|
||||
#endif
|
||||
|
||||
static const unsigned char sha256_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-256 final digest
|
||||
*/
|
||||
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] )
|
||||
{
|
||||
int ret;
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
if ( ( ret = mbedtls_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 ) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( ( ret = mbedtls_sha256_update_ret( ctx, msglen, 8 ) ) != 0 ) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* if state is in hardware, read it out */
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_read_digest_state(SHA2_256, ctx->state);
|
||||
}
|
||||
|
||||
PUT_UINT32_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_BE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_BE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_BE( ctx->state[3], output, 12 );
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
PUT_UINT32_BE( ctx->state[5], output, 20 );
|
||||
PUT_UINT32_BE( ctx->state[6], output, 24 );
|
||||
|
||||
if( ctx->is224 == 0 )
|
||||
PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||
|
||||
out:
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA2_256);
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
|
||||
unsigned char output[32] )
|
||||
{
|
||||
mbedtls_sha256_finish_ret( ctx, output );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */
|
469
components/mbedtls/port/esp_sha512.c
Normal file
469
components/mbedtls/port/esp_sha512.c
Normal file
@ -0,0 +1,469 @@
|
||||
/*
|
||||
* SHA-512 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#include "mbedtls/sha512.h"
|
||||
|
||||
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
#define UL64(x) x##ui64
|
||||
#else
|
||||
#define UL64(x) x##ULL
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "esp32/sha.h"
|
||||
|
||||
inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
|
||||
{
|
||||
return ctx->is384 ? SHA2_384 : SHA2_512;
|
||||
}
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 64-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT64_BE
|
||||
#define GET_UINT64_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint64_t) (b)[(i) ] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) + 7] ); \
|
||||
}
|
||||
#endif /* GET_UINT64_BE */
|
||||
|
||||
#ifndef PUT_UINT64_BE
|
||||
#define PUT_UINT64_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif /* PUT_UINT64_BE */
|
||||
|
||||
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_unlock_engine(sha_type(ctx));
|
||||
}
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
|
||||
if (src->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
/* Copy hardware digest state out to cloned state,
|
||||
which will be a software digest.
|
||||
|
||||
Always read 512 bits of state, even for SHA-384
|
||||
(SHA-384 state is identical to SHA-512, only
|
||||
digest is truncated.)
|
||||
*/
|
||||
esp_sha_read_digest_state(SHA2_512, dst->state);
|
||||
dst->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SHA-512 context setup
|
||||
*/
|
||||
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if( is384 == 0 )
|
||||
{
|
||||
/* SHA-512 */
|
||||
ctx->state[0] = UL64(0x6A09E667F3BCC908);
|
||||
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
|
||||
ctx->state[2] = UL64(0x3C6EF372FE94F82B);
|
||||
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
|
||||
ctx->state[4] = UL64(0x510E527FADE682D1);
|
||||
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
|
||||
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
|
||||
ctx->state[7] = UL64(0x5BE0CD19137E2179);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHA-384 */
|
||||
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
|
||||
ctx->state[1] = UL64(0x629A292A367CD507);
|
||||
ctx->state[2] = UL64(0x9159015A3070DD17);
|
||||
ctx->state[3] = UL64(0x152FECD8F70E5939);
|
||||
ctx->state[4] = UL64(0x67332667FFC00B31);
|
||||
ctx->state[5] = UL64(0x8EB44A8768581511);
|
||||
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
|
||||
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
|
||||
}
|
||||
|
||||
ctx->is384 = is384;
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_unlock_engine(sha_type(ctx));
|
||||
}
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_UNUSED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
|
||||
int is384 )
|
||||
{
|
||||
mbedtls_sha512_starts_ret( ctx, is384 );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Round constants
|
||||
*/
|
||||
static const uint64_t K[80] =
|
||||
{
|
||||
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
|
||||
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
|
||||
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
|
||||
UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
|
||||
UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
|
||||
UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
|
||||
UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
|
||||
UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
|
||||
UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
|
||||
UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
|
||||
UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
|
||||
UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
|
||||
UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
|
||||
UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
|
||||
UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
|
||||
UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
|
||||
UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
|
||||
UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
|
||||
UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
|
||||
UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
|
||||
UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
|
||||
UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
|
||||
UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
|
||||
UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
|
||||
UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
|
||||
UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
|
||||
UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
|
||||
UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
|
||||
UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
|
||||
UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
|
||||
UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
|
||||
UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
|
||||
UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
|
||||
UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
|
||||
UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
|
||||
UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
|
||||
UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
|
||||
UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
|
||||
UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
|
||||
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
|
||||
};
|
||||
|
||||
static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
|
||||
|
||||
int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
|
||||
{
|
||||
bool first_block = false;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_UNUSED) {
|
||||
/* try to use hardware for this digest */
|
||||
if (esp_sha_try_lock_engine(sha_type(ctx))) {
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_HARDWARE;
|
||||
first_block = true;
|
||||
} else {
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_block(sha_type(ctx), data, first_block);
|
||||
} else {
|
||||
mbedtls_sha512_software_process(ctx, data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
|
||||
const unsigned char data[128] )
|
||||
{
|
||||
mbedtls_internal_sha512_process( ctx, data );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
|
||||
{
|
||||
int i;
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A, B, C, D, E, F, G, H;
|
||||
|
||||
#define SHR(x,n) (x >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
|
||||
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
|
||||
|
||||
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
|
||||
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
}
|
||||
|
||||
for( ; i < 80; i++ )
|
||||
{
|
||||
W[i] = S1(W[i - 2]) + W[i - 7] +
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
|
||||
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
|
||||
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
|
||||
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
|
||||
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
|
||||
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
|
||||
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
|
||||
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
|
||||
}
|
||||
while( i < 80 );
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 process buffer
|
||||
*/
|
||||
int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
int ret;
|
||||
size_t fill;
|
||||
unsigned int left;
|
||||
|
||||
if( ilen == 0 )
|
||||
return 0;
|
||||
|
||||
left = (unsigned int) (ctx->total[0] & 0x7F);
|
||||
fill = 128 - left;
|
||||
|
||||
ctx->total[0] += (uint64_t) ilen;
|
||||
|
||||
if( ctx->total[0] < (uint64_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
if ( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 128 )
|
||||
{
|
||||
if ( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input += 128;
|
||||
ilen -= 128;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
mbedtls_sha512_update_ret( ctx, input, ilen );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static const unsigned char sha512_padding[128] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-512 final digest
|
||||
*/
|
||||
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] )
|
||||
{
|
||||
int ret;
|
||||
size_t last, padn;
|
||||
uint64_t high, low;
|
||||
unsigned char msglen[16];
|
||||
|
||||
high = ( ctx->total[0] >> 61 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT64_BE( high, msglen, 0 );
|
||||
PUT_UINT64_BE( low, msglen, 8 );
|
||||
|
||||
last = (size_t)( ctx->total[0] & 0x7F );
|
||||
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
|
||||
|
||||
if ( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 ) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 ) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* if state is in hardware, read it out */
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_read_digest_state(sha_type(ctx), ctx->state);
|
||||
}
|
||||
|
||||
PUT_UINT64_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT64_BE( ctx->state[1], output, 8 );
|
||||
PUT_UINT64_BE( ctx->state[2], output, 16 );
|
||||
PUT_UINT64_BE( ctx->state[3], output, 24 );
|
||||
PUT_UINT64_BE( ctx->state[4], output, 32 );
|
||||
PUT_UINT64_BE( ctx->state[5], output, 40 );
|
||||
|
||||
if( ctx->is384 == 0 )
|
||||
{
|
||||
PUT_UINT64_BE( ctx->state[6], output, 48 );
|
||||
PUT_UINT64_BE( ctx->state[7], output, 56 );
|
||||
}
|
||||
|
||||
out:
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_unlock_engine(sha_type(ctx));
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
|
||||
unsigned char output[64] )
|
||||
{
|
||||
mbedtls_sha512_finish_ret( ctx, output );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */
|
102
components/mbedtls/port/esp_timing.c
Normal file
102
components/mbedtls/port/esp_timing.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Portable interface to the CPU cycle counter
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
/*
|
||||
* mbedtls_timing_get_timer()m mbedtls_timing_set_delay() and
|
||||
* mbedtls_timing_set_delay only abstracted from mbedtls/library/timing.c
|
||||
* as that does not build on ESP-IDF but these 2 functions are needed for
|
||||
* DTLS (in particular mbedtls_ssl_set_timer_cb() must be called for DTLS
|
||||
* which requires these 2 delay functions).
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_ESP_TIMING_C)
|
||||
|
||||
#include <sys/time.h>
|
||||
#include "mbedtls/timing.h"
|
||||
|
||||
struct _hr_time
|
||||
{
|
||||
struct timeval start;
|
||||
};
|
||||
|
||||
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
|
||||
{
|
||||
struct _hr_time *t = (struct _hr_time *) val;
|
||||
|
||||
if( reset )
|
||||
{
|
||||
gettimeofday( &t->start, NULL );
|
||||
return( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long delta;
|
||||
struct timeval now;
|
||||
gettimeofday( &now, NULL );
|
||||
delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul
|
||||
+ ( now.tv_usec - t->start.tv_usec ) / 1000;
|
||||
return( delta );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set delays to watch
|
||||
*/
|
||||
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms )
|
||||
{
|
||||
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
|
||||
|
||||
ctx->int_ms = int_ms;
|
||||
ctx->fin_ms = fin_ms;
|
||||
|
||||
if( fin_ms != 0 )
|
||||
(void) mbedtls_timing_get_timer( &ctx->timer, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Get number of delays expired
|
||||
*/
|
||||
int mbedtls_timing_get_delay( void *data )
|
||||
{
|
||||
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
|
||||
unsigned long elapsed_ms;
|
||||
|
||||
if( ctx->fin_ms == 0 )
|
||||
return( -1 );
|
||||
|
||||
elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 );
|
||||
|
||||
if( elapsed_ms >= ctx->fin_ms )
|
||||
return( 2 );
|
||||
|
||||
if( elapsed_ms >= ctx->int_ms )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ESP_TIMING_C */
|
69
components/mbedtls/port/include/aes_alt.h
Normal file
69
components/mbedtls/port/include/aes_alt.h
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* \file aes_alt.h
|
||||
*
|
||||
* \brief AES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifndef AES_ALT_H
|
||||
#define AES_ALT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AES_ALT)
|
||||
#include "esp32/aes.h"
|
||||
|
||||
typedef esp_aes_context mbedtls_aes_context;
|
||||
|
||||
#define mbedtls_aes_init esp_aes_init
|
||||
#define mbedtls_aes_free esp_aes_free
|
||||
#define mbedtls_aes_setkey_enc esp_aes_setkey
|
||||
#define mbedtls_aes_setkey_dec esp_aes_setkey
|
||||
#define mbedtls_aes_crypt_ecb esp_aes_crypt_ecb
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
#define mbedtls_aes_crypt_cbc esp_aes_crypt_cbc
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
#define mbedtls_aes_crypt_cfb128 esp_aes_crypt_cfb128
|
||||
#define mbedtls_aes_crypt_cfb8 esp_aes_crypt_cfb8
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
#define mbedtls_aes_crypt_ctr esp_aes_crypt_ctr
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||
#define mbedtls_aes_crypt_ofb esp_aes_crypt_ofb
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
typedef esp_aes_xts_context mbedtls_aes_xts_context;
|
||||
#define mbedtls_aes_xts_init esp_aes_xts_init
|
||||
#define mbedtls_aes_xts_free esp_aes_xts_free
|
||||
#define mbedtls_aes_xts_setkey_enc esp_aes_xts_setkey_enc
|
||||
#define mbedtls_aes_xts_setkey_dec esp_aes_xts_setkey_dec
|
||||
#define mbedtls_aes_crypt_xts esp_aes_crypt_xts
|
||||
#endif
|
||||
#define mbedtls_internal_aes_encrypt esp_internal_aes_encrypt
|
||||
#define mbedtls_internal_aes_decrypt esp_internal_aes_decrypt
|
||||
#endif /* MBEDTLS_AES_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
359
components/mbedtls/port/include/esp32/aes.h
Normal file
359
components/mbedtls/port/include/esp32/aes.h
Normal file
@ -0,0 +1,359 @@
|
||||
/**
|
||||
* \brief AES block cipher, ESP32 hardware accelerated version
|
||||
* Based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ESP_AES_H
|
||||
#define ESP_AES_H
|
||||
|
||||
#include "esp_types.h"
|
||||
#include "esp32/rom/aes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* padlock.c and aesni.c rely on these values! */
|
||||
#define ESP_AES_ENCRYPT 1
|
||||
#define ESP_AES_DECRYPT 0
|
||||
|
||||
#define ERR_ESP_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define ERR_ESP_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t key_bytes;
|
||||
volatile uint8_t key_in_hardware; /* This variable is used for fault injection checks, so marked volatile to avoid optimisation */
|
||||
uint8_t key[32];
|
||||
} esp_aes_context;
|
||||
|
||||
/**
|
||||
* \brief The AES XTS context-type definition.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_aes_context crypt; /*!< The AES context to use for AES block
|
||||
encryption or decryption. */
|
||||
esp_aes_context tweak; /*!< The AES context used for tweak
|
||||
computation. */
|
||||
} esp_aes_xts_context;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Lock access to AES hardware unit
|
||||
*
|
||||
* AES hardware unit can only be used by one
|
||||
* consumer at a time.
|
||||
*
|
||||
* esp_aes_xxx API calls automatically manage locking & unlocking of
|
||||
* hardware, this function is only needed if you want to call
|
||||
* ets_aes_xxx functions directly.
|
||||
*/
|
||||
void esp_aes_acquire_hardware( void );
|
||||
|
||||
/**
|
||||
* \brief Unlock access to AES hardware unit
|
||||
*
|
||||
* esp_aes_xxx API calls automatically manage locking & unlocking of
|
||||
* hardware, this function is only needed if you want to call
|
||||
* ets_aes_xxx functions directly.
|
||||
*/
|
||||
void esp_aes_release_hardware( void );
|
||||
|
||||
/**
|
||||
* \brief Initialize AES context
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
*/
|
||||
void esp_aes_init( esp_aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear AES context
|
||||
*
|
||||
* \param ctx AES context to be cleared
|
||||
*/
|
||||
void esp_aes_free( esp_aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified AES XTS context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context.
|
||||
*
|
||||
* \param ctx The AES XTS context to initialize.
|
||||
*/
|
||||
void esp_aes_xts_init( esp_aes_xts_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified AES XTS context.
|
||||
*
|
||||
* \param ctx The AES XTS context to clear.
|
||||
*/
|
||||
void esp_aes_xts_free( esp_aes_xts_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief AES set key schedule (encryption or decryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keybits must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int esp_aes_setkey( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits );
|
||||
|
||||
/**
|
||||
* \brief AES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int esp_aes_crypt_ecb( esp_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief AES-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or ERR_AES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int esp_aes_crypt_cbc( esp_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
|
||||
/**
|
||||
* \brief AES-CFB128 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int esp_aes_crypt_cfb128( esp_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CFB8 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int esp_aes_crypt_cfb8( esp_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int esp_aes_crypt_ctr( esp_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief This function prepares an XTS context for encryption and
|
||||
* sets the encryption key.
|
||||
*
|
||||
* \param ctx The AES XTS context to which the key should be bound.
|
||||
* \param key The encryption key. This is comprised of the XTS key1
|
||||
* concatenated with the XTS key2.
|
||||
* \param keybits The size of \p key passed in bits. Valid options are:
|
||||
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
|
||||
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
/**
|
||||
* \brief This function performs an AES-OFB (Output Feedback Mode)
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param length The length of the input data.
|
||||
* \param iv_off The offset in IV (updated after use).
|
||||
* It must point to a valid \c size_t.
|
||||
* \param iv The initialization vector (updated after use).
|
||||
* It must be a readable and writeable buffer of \c 16 Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and of size \p length Bytes.
|
||||
* \param output The buffer holding the output data.
|
||||
* It must be writeable and of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int esp_aes_crypt_ofb( esp_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief This function prepares an XTS context for decryption and
|
||||
* sets the decryption key.
|
||||
*
|
||||
* \param ctx The AES XTS context to which the key should be bound.
|
||||
* \param key The decryption key. This is comprised of the XTS key1
|
||||
* concatenated with the XTS key2.
|
||||
* \param keybits The size of \p key passed in bits. Valid options are:
|
||||
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
|
||||
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
|
||||
/**
|
||||
* \brief Internal AES block encryption function
|
||||
* (Only exposed to allow overriding it,
|
||||
* see AES_ENCRYPT_ALT)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param input Plaintext block
|
||||
* \param output Output (ciphertext) block
|
||||
*/
|
||||
int esp_internal_aes_encrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] );
|
||||
|
||||
/** Deprecated, see esp_aes_internal_encrypt */
|
||||
void esp_aes_encrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* \brief Internal AES block decryption function
|
||||
* (Only exposed to allow overriding it,
|
||||
* see AES_DECRYPT_ALT)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param input Ciphertext block
|
||||
* \param output Output (plaintext) block
|
||||
*/
|
||||
int esp_internal_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] );
|
||||
|
||||
/** Deprecated, see esp_aes_internal_decrypt */
|
||||
void esp_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) __attribute__((deprecated));
|
||||
|
||||
/** AES-XTS buffer encryption/decryption */
|
||||
int esp_aes_crypt_xts( esp_aes_xts_context *ctx, int mode, size_t length, const unsigned char data_unit[16], const unsigned char *input, unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aes.h */
|
211
components/mbedtls/port/include/esp32/sha.h
Normal file
211
components/mbedtls/port/include/esp32/sha.h
Normal file
@ -0,0 +1,211 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ESP_SHA_H_
|
||||
#define _ESP_SHA_H_
|
||||
|
||||
#include "esp32/rom/sha.h"
|
||||
#include "esp_types.h"
|
||||
|
||||
/** @brief Low-level support functions for the hardware SHA engine
|
||||
*
|
||||
* @note If you're looking for a SHA API to use, try mbedtls component
|
||||
* mbedtls/shaXX.h. That API supports hardware acceleration.
|
||||
*
|
||||
* The API in this header provides some building blocks for implementing a
|
||||
* full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
|
||||
*
|
||||
* Some technical details about the hardware SHA engine:
|
||||
*
|
||||
* - SHA accelerator engine calculates one digest at a time, per SHA
|
||||
* algorithm type. It initialises and maintains the digest state
|
||||
* internally. It is possible to read out an in-progress SHA digest
|
||||
* state, but it is not possible to restore a SHA digest state
|
||||
* into the engine.
|
||||
*
|
||||
* - The memory block SHA_TEXT_BASE is shared between all SHA digest
|
||||
* engines, so all engines must be idle before this memory block is
|
||||
* modified.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Defined in esp32/rom/sha.h */
|
||||
typedef enum SHA_TYPE esp_sha_type;
|
||||
|
||||
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
|
||||
*
|
||||
* @note For more versatile SHA calculations, where data doesn't need
|
||||
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
|
||||
* hardware-accelerated mbedTLS implementation is also faster when
|
||||
* hashing large amounts of data.
|
||||
*
|
||||
* @note It is not necessary to lock any SHA hardware before calling
|
||||
* this function, thread safety is managed internally.
|
||||
*
|
||||
* @note If a TLS connection is open then this function may block
|
||||
* indefinitely waiting for a SHA engine to become available. Use the
|
||||
* mbedTLS SHA API to avoid this problem.
|
||||
*
|
||||
* @param sha_type SHA algorithm to use.
|
||||
*
|
||||
* @param input Input data buffer.
|
||||
*
|
||||
* @param ilen Length of input data in bytes.
|
||||
*
|
||||
* @param output Buffer for output SHA digest. Output is 20 bytes for
|
||||
* sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
|
||||
* sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
|
||||
*/
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
|
||||
|
||||
/* @brief Begin to execute a single SHA block operation
|
||||
*
|
||||
* @note This is a piece of a SHA algorithm, rather than an entire SHA
|
||||
* algorithm.
|
||||
*
|
||||
* @note Call esp_sha_try_lock_engine() before calling this
|
||||
* function. Do not call esp_sha_lock_memory_block() beforehand, this
|
||||
* is done inside the function.
|
||||
*
|
||||
* @param sha_type SHA algorithm to use.
|
||||
*
|
||||
* @param data_block Pointer to block of data. Block size is
|
||||
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
|
||||
* SHA2_384/SHA2_512 = 128 bytes)
|
||||
*
|
||||
* @param is_first_block If this parameter is true, the SHA state will
|
||||
* be initialised (with the initial state of the given SHA algorithm)
|
||||
* before the block is calculated. If false, the existing state of the
|
||||
* SHA engine will be used.
|
||||
*
|
||||
* @return As a performance optimisation, this function returns before
|
||||
* the SHA block operation is complete. Both this function and
|
||||
* esp_sha_read_state() will automatically wait for any previous
|
||||
* operation to complete before they begin. If using the SHA registers
|
||||
* directly in another way, call esp_sha_wait_idle() after calling this
|
||||
* function but before accessing the SHA registers.
|
||||
*/
|
||||
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
|
||||
|
||||
/** @brief Read out the current state of the SHA digest loaded in the engine.
|
||||
*
|
||||
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
|
||||
*
|
||||
* @note Call esp_sha_try_lock_engine() before calling this
|
||||
* function. Do not call esp_sha_lock_memory_block() beforehand, this
|
||||
* is done inside the function.
|
||||
*
|
||||
* If the SHA suffix padding block has been executed already, the
|
||||
* value that is read is the SHA digest (in big endian
|
||||
* format). Otherwise, the value that is read is an interim SHA state.
|
||||
*
|
||||
* @note If sha_type is SHA2_384, only 48 bytes of state will be read.
|
||||
* This is enough for the final SHA2_384 digest, but if you want the
|
||||
* interim SHA-384 state (to continue digesting) then pass SHA2_512 instead.
|
||||
*
|
||||
* @param sha_type SHA algorithm in use.
|
||||
*
|
||||
* @param state Pointer to a memory buffer to hold the SHA state. Size
|
||||
* is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512).
|
||||
*
|
||||
*/
|
||||
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
|
||||
|
||||
/**
|
||||
* @brief Obtain exclusive access to a particular SHA engine
|
||||
*
|
||||
* @param sha_type Type of SHA engine to use.
|
||||
*
|
||||
* Blocks until engine is available. Note: Can block indefinitely
|
||||
* while a TLS connection is open, suggest using
|
||||
* esp_sha_try_lock_engine() and failing over to software SHA.
|
||||
*/
|
||||
void esp_sha_lock_engine(esp_sha_type sha_type);
|
||||
|
||||
/**
|
||||
* @brief Try and obtain exclusive access to a particular SHA engine
|
||||
*
|
||||
* @param sha_type Type of SHA engine to use.
|
||||
*
|
||||
* @return Returns true if the SHA engine is locked for exclusive
|
||||
* use. Call esp_sha_unlock_sha_engine() when done. Returns false if
|
||||
* the SHA engine is already in use, caller should use software SHA
|
||||
* algorithm for this digest.
|
||||
*/
|
||||
bool esp_sha_try_lock_engine(esp_sha_type sha_type);
|
||||
|
||||
/**
|
||||
* @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
|
||||
*
|
||||
* @param sha_type Type of engine to release.
|
||||
*/
|
||||
void esp_sha_unlock_engine(esp_sha_type sha_type);
|
||||
|
||||
/**
|
||||
* @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
|
||||
*
|
||||
* This memory block is shared across all the SHA algorithm types.
|
||||
*
|
||||
* Caller should have already locked a SHA engine before calling this function.
|
||||
*
|
||||
* Note that it is possible to obtain exclusive access to the memory block even
|
||||
* while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
|
||||
* to ensure the SHA engine is not reading from the memory block in hardware.
|
||||
*
|
||||
* @note This function enters a critical section. Do not block while holding this lock.
|
||||
*
|
||||
* @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
|
||||
*
|
||||
* Call esp_sha_unlock_memory_block() when done.
|
||||
*/
|
||||
void esp_sha_lock_memory_block(void);
|
||||
|
||||
/**
|
||||
* @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
|
||||
*
|
||||
* Caller should have already locked a SHA engine before calling this function.
|
||||
*
|
||||
* This function releases the critical section entered by esp_sha_lock_memory_block().
|
||||
*
|
||||
* Call following esp_sha_lock_memory_block().
|
||||
*/
|
||||
void esp_sha_unlock_memory_block(void);
|
||||
|
||||
/** @brief Wait for the SHA engine to finish any current operation
|
||||
*
|
||||
* @note This function does not ensure exclusive access to any SHA
|
||||
* engine. Caller should use esp_sha_try_lock_engine() and
|
||||
* esp_sha_lock_memory_block() as required.
|
||||
*
|
||||
* @note Functions declared in this header file wait for SHA engine
|
||||
* completion automatically, so you don't need to use this API for
|
||||
* these. However if accessing SHA registers directly, you will need
|
||||
* to call this before accessing SHA registers if using the
|
||||
* esp_sha_block() function.
|
||||
*
|
||||
* @note This function busy-waits, so wastes CPU resources.
|
||||
* Best to delay calling until you are about to need it.
|
||||
*
|
||||
*/
|
||||
void esp_sha_wait_idle(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
20
components/mbedtls/port/include/esp_mem.h
Normal file
20
components/mbedtls/port/include/esp_mem.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *esp_mbedtls_mem_calloc(size_t n, size_t size);
|
||||
void esp_mbedtls_mem_free(void *ptr);
|
78
components/mbedtls/port/include/mbedtls/bignum.h
Normal file
78
components/mbedtls/port/include/mbedtls/bignum.h
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef __ESP_MBEDTLS_BIGNUM_H__
|
||||
#define __ESP_MBEDTLS_BIGNUM_H__
|
||||
|
||||
#include_next "mbedtls/bignum.h"
|
||||
|
||||
/**
|
||||
* This is a wrapper for the main mbedtls/bignum.h. This wrapper
|
||||
* provides a few additional ESP32-only functions.
|
||||
*
|
||||
* This is because we don't set MBEDTLS_BIGNUM_ALT in the same way we
|
||||
* do for AES, SHA, etc. Because we still use most of the bignum.h
|
||||
* implementation and just replace a few hardware accelerated
|
||||
* functions (see MBEDTLS_MPI_EXP_MOD_ALT & MBEDTLS_MPI_MUL_MPI_ALT in
|
||||
* esp_config.h).
|
||||
*
|
||||
* @note Unlike the other hardware accelerator support functions in esp32/hwcrypto, there is no
|
||||
* generic "hwcrypto/bignum.h" header for using these functions without mbedTLS. The reason for this
|
||||
* is that all of the function implementations depend strongly upon the mbedTLS MPI implementation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Lock access to RSA Accelerator (MPI/bignum operations)
|
||||
*
|
||||
* RSA Accelerator hardware unit can only be used by one
|
||||
* consumer at a time.
|
||||
*
|
||||
* @note This function is non-recursive (do not call it twice from the
|
||||
* same task.)
|
||||
*
|
||||
* @note You do not need to call this if you are using the mbedTLS bignum.h
|
||||
* API or esp_mpi_xxx functions. This function is only needed if you
|
||||
* want to call ROM RSA functions or access the registers directly.
|
||||
*
|
||||
*/
|
||||
void esp_mpi_acquire_hardware(void);
|
||||
|
||||
/**
|
||||
* @brief Unlock access to RSA Accelerator (MPI/bignum operations)
|
||||
*
|
||||
* Has to be called once for each call to esp_mpi_acquire_hardware().
|
||||
*
|
||||
* @note You do not need to call this if you are using the mbedTLS bignum.h
|
||||
* API or esp_mpi_xxx functions. This function is only needed if you
|
||||
* want to call ROM RSA functions or access the registers directly.
|
||||
*/
|
||||
void esp_mpi_release_hardware(void);
|
||||
|
||||
/* @brief MPI modular mupltiplication function
|
||||
*
|
||||
* Calculates Z = (X * Y) mod M using MPI hardware acceleration.
|
||||
*
|
||||
* This is not part of the standard mbedTLS bignum API.
|
||||
*
|
||||
* @note All of X, Y & Z should be less than 4096 bit long or an error is returned.
|
||||
*
|
||||
* @param Z Result bignum, should be pre-initialised with mbedtls_mpi_init().
|
||||
* @param X First multiplication argument.
|
||||
* @param Y Second multiplication argument.
|
||||
* @param M Modulus value for result.
|
||||
*
|
||||
* @return 0 on success, mbedTLS MPI error codes on failure.
|
||||
*/
|
||||
int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M);
|
||||
|
||||
#endif
|
2293
components/mbedtls/port/include/mbedtls/esp_config.h
Normal file
2293
components/mbedtls/port/include/mbedtls/esp_config.h
Normal file
File diff suppressed because it is too large
Load Diff
59
components/mbedtls/port/include/mbedtls/esp_debug.h
Normal file
59
components/mbedtls/port/include/mbedtls/esp_debug.h
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ESP_DEBUG_H_
|
||||
#define _ESP_DEBUG_H_
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#ifdef CONFIG_MBEDTLS_DEBUG
|
||||
|
||||
/** @brief Enable mbedTLS debug logging via the esp_log mechanism.
|
||||
*
|
||||
* mbedTLS internal debugging is filtered from a specified mbedTLS
|
||||
* threshold level to esp_log level at runtime:
|
||||
*
|
||||
* - 1 - Warning
|
||||
* - 2 - Info
|
||||
* - 3 - Debug
|
||||
* - 4 - Verbose
|
||||
*
|
||||
* (Note that mbedTLS debug thresholds are not always consistently used.)
|
||||
*
|
||||
* This function will set the esp log level for "mbedtls" to the specified mbedTLS
|
||||
* threshold level that matches. However, the overall max ESP log level must be set high
|
||||
* enough in menuconfig, or some messages may be filtered at compile time.
|
||||
*
|
||||
* @param conf mbedtls_ssl_config structure
|
||||
* @param mbedTLS debug threshold, 0-4. Messages are filtered at runtime.
|
||||
*/
|
||||
void mbedtls_esp_enable_debug_log(mbedtls_ssl_config *conf, int threshold);
|
||||
|
||||
/** @brief Disable mbedTLS debug logging via the esp_log mechanism.
|
||||
*
|
||||
*/
|
||||
void mbedtls_esp_disable_debug_log(mbedtls_ssl_config *conf);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_DEBUG_H__ */
|
57
components/mbedtls/port/include/sha1_alt.h
Normal file
57
components/mbedtls/port/include/sha1_alt.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* SHA-1 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef _SHA1_ALT_H_
|
||||
#define _SHA1_ALT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA1_HARDWARE, /* using hardware SHA engine */
|
||||
ESP_MBEDTLS_SHA1_SOFTWARE, /* using software SHA */
|
||||
} esp_mbedtls_sha1_mode;
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
esp_mbedtls_sha1_mode mode;
|
||||
}
|
||||
mbedtls_sha1_context;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
57
components/mbedtls/port/include/sha256_alt.h
Normal file
57
components/mbedtls/port/include/sha256_alt.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* SHA-256 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef _SHA256_ALT_H_
|
||||
#define _SHA256_ALT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
|
||||
ESP_MBEDTLS_SHA256_SOFTWARE, /* using software SHA */
|
||||
} esp_mbedtls_sha256_mode;
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||
esp_mbedtls_sha256_mode mode;
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
57
components/mbedtls/port/include/sha512_alt.h
Normal file
57
components/mbedtls/port/include/sha512_alt.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* SHA-512 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef _SHA512_ALT_H_
|
||||
#define _SHA512_ALT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA512_HARDWARE, /* using hardware SHA engine */
|
||||
ESP_MBEDTLS_SHA512_SOFTWARE, /* using software SHA */
|
||||
} esp_mbedtls_sha512_mode;
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[128]; /*!< data block being processed */
|
||||
int is384; /*!< 0 => SHA-512, else SHA-384 */
|
||||
esp_mbedtls_sha512_mode mode;
|
||||
}
|
||||
mbedtls_sha512_context;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
94
components/mbedtls/port/mbedtls_debug.c
Normal file
94
components/mbedtls/port/mbedtls_debug.c
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/esp_debug.h"
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_DEBUG
|
||||
static const char *TAG = "mbedtls";
|
||||
|
||||
static void mbedtls_esp_debug(void *ctx, int level,
|
||||
const char *file, int line,
|
||||
const char *str);
|
||||
|
||||
void mbedtls_esp_enable_debug_log(mbedtls_ssl_config *conf, int threshold)
|
||||
{
|
||||
esp_log_level_t level = ESP_LOG_NONE;
|
||||
mbedtls_debug_set_threshold(threshold);
|
||||
mbedtls_ssl_conf_dbg(conf, mbedtls_esp_debug, NULL);
|
||||
switch(threshold) {
|
||||
case 1:
|
||||
level = ESP_LOG_WARN;
|
||||
break;
|
||||
case 2:
|
||||
level = ESP_LOG_INFO;
|
||||
break;
|
||||
case 3:
|
||||
level = ESP_LOG_DEBUG;
|
||||
break;
|
||||
case 4:
|
||||
level = ESP_LOG_VERBOSE;
|
||||
break;
|
||||
}
|
||||
esp_log_level_set(TAG, level);
|
||||
}
|
||||
|
||||
void mbedtls_esp_disable_debug_log(mbedtls_ssl_config *conf)
|
||||
{
|
||||
mbedtls_ssl_conf_dbg(conf, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Default mbedtls debug function that translates mbedTLS debug output
|
||||
to ESP_LOGx debug output.
|
||||
*/
|
||||
static void mbedtls_esp_debug(void *ctx, int level,
|
||||
const char *file, int line,
|
||||
const char *str)
|
||||
{
|
||||
char *file_sep;
|
||||
|
||||
/* Shorten 'file' from the whole file path to just the filename
|
||||
|
||||
This is a bit wasteful because the macros are compiled in with
|
||||
the full _FILE_ path in each case.
|
||||
*/
|
||||
file_sep = rindex(file, '/');
|
||||
if(file_sep)
|
||||
file = file_sep+1;
|
||||
|
||||
switch(level) {
|
||||
case 1:
|
||||
ESP_LOGW(TAG, "%s:%d %s", file, line, str);
|
||||
break;
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "%s:%d %s", file, line, str);
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGD(TAG, "%s:%d %s", file, line, str);
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGV(TAG, "%s:%d %s", file, line, str);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unexpected log level %d: %s", level, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
451
components/mbedtls/port/net_sockets.c
Normal file
451
components/mbedtls/port/net_sockets.c
Normal file
@ -0,0 +1,451 @@
|
||||
/*
|
||||
* TCP/IP or UDP/IP networking functions
|
||||
* modified for LWIP support on ESP32
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2015 Angus Gratton
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_NET_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_time time
|
||||
#define mbedtls_time_t time_t
|
||||
#endif
|
||||
|
||||
#include "mbedtls/net_sockets.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Prepare for using the sockets interface
|
||||
*/
|
||||
static int net_prepare( void )
|
||||
{
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a context
|
||||
*/
|
||||
void mbedtls_net_init( mbedtls_net_context *ctx )
|
||||
{
|
||||
ctx->fd = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiate a TCP connection with host:port and the given protocol
|
||||
*/
|
||||
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
|
||||
{
|
||||
int ret;
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
|
||||
if ( ( ret = net_prepare() ) != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/* Do name resolution with both IPv6 and IPv4 */
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
|
||||
if ( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_UNKNOWN_HOST );
|
||||
}
|
||||
|
||||
/* Try the sockaddrs until a connection succeeds */
|
||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
|
||||
int fd = socket( cur->ai_family, cur->ai_socktype, cur->ai_protocol );
|
||||
|
||||
if ( fd < 0 ) {
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( connect( fd, cur->ai_addr, cur->ai_addrlen ) == 0 ) {
|
||||
ctx->fd = fd; // connected!
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
close( fd );
|
||||
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
|
||||
}
|
||||
|
||||
freeaddrinfo( addr_list );
|
||||
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a listening socket on bind_ip:port
|
||||
*/
|
||||
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
|
||||
{
|
||||
int ret;
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
struct sockaddr_in *serv_addr = NULL;
|
||||
#if SO_REUSE
|
||||
int n = 1;
|
||||
#endif
|
||||
|
||||
if ( ( ret = net_prepare() ) != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/* Bind to IPv6 and/or IPv4, but only in the desired protocol */
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
|
||||
if ( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_UNKNOWN_HOST );
|
||||
}
|
||||
|
||||
/* Try the sockaddrs until a binding succeeds */
|
||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
|
||||
int fd = socket( cur->ai_family, cur->ai_socktype, cur->ai_protocol );
|
||||
if ( fd < 0 ) {
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*SO_REUSEADDR option dafault is disable in source code(lwip)*/
|
||||
#if SO_REUSE
|
||||
if ( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &n, sizeof( n ) ) != 0 ) {
|
||||
close( fd );
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/*bind interface dafault don't process the addr is 0xffffffff for TCP Protocol*/
|
||||
serv_addr = (struct sockaddr_in *)cur->ai_addr;
|
||||
serv_addr->sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
|
||||
if ( bind( fd, (struct sockaddr *)serv_addr, cur->ai_addrlen ) != 0 ) {
|
||||
close( fd );
|
||||
ret = MBEDTLS_ERR_NET_BIND_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Listen only makes sense for TCP */
|
||||
if ( proto == MBEDTLS_NET_PROTO_TCP ) {
|
||||
if ( listen( fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) {
|
||||
close( fd );
|
||||
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* I we ever get there, it's a success */
|
||||
ctx->fd = fd;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo( addr_list );
|
||||
|
||||
return ( ret );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the requested operation would be blocking on a non-blocking socket
|
||||
* and thus 'failed' with a negative return value.
|
||||
*
|
||||
* Note: on a blocking socket this function always returns 0!
|
||||
*/
|
||||
static int net_would_block( const mbedtls_net_context *ctx )
|
||||
{
|
||||
int error = errno;
|
||||
|
||||
/*
|
||||
* Never return 'WOULD BLOCK' on a non-blocking socket
|
||||
*/
|
||||
if ( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK ) {
|
||||
errno = error;
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
switch ( errno = error ) {
|
||||
#if defined EAGAIN
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
return ( 1 );
|
||||
}
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept a connection from a remote client
|
||||
*/
|
||||
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||
mbedtls_net_context *client_ctx,
|
||||
void *client_ip, size_t buf_size, size_t *ip_len )
|
||||
{
|
||||
int ret;
|
||||
int type;
|
||||
|
||||
struct sockaddr_in client_addr;
|
||||
|
||||
socklen_t n = (socklen_t) sizeof( client_addr );
|
||||
socklen_t type_len = (socklen_t) sizeof( type );
|
||||
|
||||
/* Is this a TCP or UDP socket? */
|
||||
if ( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
|
||||
(void *) &type, (socklen_t *) &type_len ) != 0 ||
|
||||
( type != SOCK_STREAM && type != SOCK_DGRAM ) ) {
|
||||
return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
||||
}
|
||||
|
||||
if ( type == SOCK_STREAM ) {
|
||||
/* TCP: actual accept() */
|
||||
ret = client_ctx->fd = (int) accept( bind_ctx->fd,
|
||||
(struct sockaddr *) &client_addr, &n );
|
||||
} else {
|
||||
/* UDP: wait for a message, but keep it in the queue */
|
||||
char buf[1] = { 0 };
|
||||
|
||||
ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
|
||||
(struct sockaddr *) &client_addr, &n );
|
||||
|
||||
}
|
||||
|
||||
if ( ret < 0 ) {
|
||||
if ( net_would_block( bind_ctx ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
}
|
||||
|
||||
return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
||||
}
|
||||
|
||||
/* UDP: hijack the listening socket to communicate with the client,
|
||||
* then bind a new socket to accept new connections */
|
||||
if ( type != SOCK_STREAM ) {
|
||||
struct sockaddr_in local_addr;
|
||||
int one = 1;
|
||||
|
||||
if ( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
||||
}
|
||||
|
||||
client_ctx->fd = bind_ctx->fd;
|
||||
bind_ctx->fd = -1; /* In case we exit early */
|
||||
|
||||
n = sizeof( struct sockaddr_in );
|
||||
if ( getsockname( client_ctx->fd,
|
||||
(struct sockaddr *) &local_addr, &n ) != 0 ||
|
||||
( bind_ctx->fd = (int) socket( AF_INET,
|
||||
SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
|
||||
setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &one, sizeof( one ) ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_SOCKET_FAILED );
|
||||
}
|
||||
|
||||
if ( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_BIND_FAILED );
|
||||
}
|
||||
}
|
||||
|
||||
if ( client_ip != NULL ) {
|
||||
struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
|
||||
*ip_len = sizeof( addr4->sin_addr.s_addr );
|
||||
|
||||
if ( buf_size < *ip_len ) {
|
||||
return ( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
|
||||
}
|
||||
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the socket blocking or non-blocking
|
||||
*/
|
||||
int mbedtls_net_set_block( mbedtls_net_context *ctx )
|
||||
{
|
||||
return ( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) & ~O_NONBLOCK ) );
|
||||
}
|
||||
|
||||
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
|
||||
{
|
||||
return ( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Portable usleep helper
|
||||
*/
|
||||
void mbedtls_net_usleep( unsigned long usec )
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = usec / 1000000;
|
||||
tv.tv_usec = usec % 1000000;
|
||||
select( 0, NULL, NULL, NULL, &tv );
|
||||
}
|
||||
|
||||
/*
|
||||
* Read at most 'len' characters
|
||||
*/
|
||||
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
if ( fd < 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||
}
|
||||
|
||||
ret = (int) read( fd, buf, len );
|
||||
|
||||
if ( ret < 0 ) {
|
||||
if ( net_would_block( ctx ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
}
|
||||
|
||||
if ( errno == EPIPE || errno == ECONNRESET ) {
|
||||
return ( MBEDTLS_ERR_NET_CONN_RESET );
|
||||
}
|
||||
|
||||
if ( errno == EINTR ) {
|
||||
return ( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
}
|
||||
|
||||
return ( MBEDTLS_ERR_NET_RECV_FAILED );
|
||||
}
|
||||
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Read at most 'len' characters, blocking for at most 'timeout' ms
|
||||
*/
|
||||
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
|
||||
uint32_t timeout )
|
||||
{
|
||||
int ret;
|
||||
struct timeval tv;
|
||||
fd_set read_fds;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
if ( fd < 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||
}
|
||||
|
||||
FD_ZERO( &read_fds );
|
||||
FD_SET( fd, &read_fds );
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = ( timeout % 1000 ) * 1000;
|
||||
|
||||
ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
|
||||
|
||||
/* Zero fds ready means we timed out */
|
||||
if ( ret == 0 ) {
|
||||
return ( MBEDTLS_ERR_SSL_TIMEOUT );
|
||||
}
|
||||
|
||||
if ( ret < 0 ) {
|
||||
if ( errno == EINTR ) {
|
||||
return ( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
}
|
||||
|
||||
return ( MBEDTLS_ERR_NET_RECV_FAILED );
|
||||
}
|
||||
|
||||
/* This call will not block */
|
||||
return ( mbedtls_net_recv( ctx, buf, len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write at most 'len' characters
|
||||
*/
|
||||
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
if ( fd < 0 ) {
|
||||
return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||
}
|
||||
|
||||
ret = (int) write( fd, buf, len );
|
||||
|
||||
if ( ret < 0 ) {
|
||||
if ( net_would_block( ctx ) != 0 ) {
|
||||
return ( MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||
}
|
||||
|
||||
if ( errno == EPIPE || errno == ECONNRESET ) {
|
||||
return ( MBEDTLS_ERR_NET_CONN_RESET );
|
||||
}
|
||||
|
||||
if ( errno == EINTR ) {
|
||||
return ( MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||
}
|
||||
|
||||
return ( MBEDTLS_ERR_NET_SEND_FAILED );
|
||||
}
|
||||
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Gracefully close the connection
|
||||
*/
|
||||
void mbedtls_net_free( mbedtls_net_context *ctx )
|
||||
{
|
||||
if ( ctx->fd == -1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
shutdown( ctx->fd, 2 );
|
||||
close( ctx->fd );
|
||||
|
||||
ctx->fd = -1;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_NET_C */
|
9
components/mbedtls/test/CMakeLists.txt
Normal file
9
components/mbedtls/test/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES unity test_utils mbedtls)
|
||||
|
||||
idf_component_get_property(mbedtls mbedtls COMPONENT_LIB)
|
||||
target_compile_definitions(${mbedtls} INTERFACE "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedtls PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedcrypto PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedx509 PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
5
components/mbedtls/test/component.mk
Normal file
5
components/mbedtls/test/component.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
#Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
71
components/mbedtls/test/test_aes_perf.c
Normal file
71
components/mbedtls/test/test_aes_perf.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* mbedTLS AES performance test
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/aes.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
TEST_CASE("mbedtls AES performance", "[aes]")
|
||||
{
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 32*1024;
|
||||
mbedtls_aes_context ctx;
|
||||
int64_t start, end;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
|
||||
memset(iv, 0xEE, 16);
|
||||
memset(key, 0x44, 16);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
mbedtls_aes_init(&ctx);
|
||||
mbedtls_aes_setkey_enc(&ctx, key, 128);
|
||||
|
||||
start = esp_timer_get_time();
|
||||
for (int c = 0; c < CALLS; c++) {
|
||||
memset(buf, 0xAA, CALL_SZ);
|
||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, buf, buf);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
|
||||
/* Sanity check: make sure the last ciphertext block matches
|
||||
what we expect to see.
|
||||
|
||||
Last block produced via this Python:
|
||||
import os, binascii
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
key = b'\x44' * 16
|
||||
iv = b'\xee' * 16
|
||||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
|
||||
encryptor = cipher.encryptor()
|
||||
ct = encryptor.update(b'\xaa' * 256 * 32 * 1024) + encryptor.finalize()
|
||||
print(binascii.hexlify(ct[-16:]))
|
||||
*/
|
||||
const uint8_t expected_last_block[] = {
|
||||
0x50, 0x81, 0xe0, 0xe1, 0x15, 0x2f, 0x14, 0xe9,
|
||||
0x97, 0xa0, 0xc6, 0xe6, 0x36, 0xf3, 0x5c, 0x25,
|
||||
};
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16);
|
||||
|
||||
free(buf);
|
||||
|
||||
float usecs = end - start;
|
||||
// bytes/usec = MB/sec
|
||||
float mb_sec = (CALL_SZ * CALLS) / usecs;
|
||||
printf("Encryption rate %.3fMB/sec\n", mb_sec);
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_AES
|
||||
// Don't put a hard limit on software AES performance (software is approx 2.3MB/sec on Release config)
|
||||
TEST_PERFORMANCE_GREATER_THAN(AES_CBC_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
56
components/mbedtls/test/test_apb_dport_access.c
Normal file
56
components/mbedtls/test/test_apb_dport_access.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* Implementation of utility functions to verify
|
||||
unit tests aren't performing SMP-unsafe DPORT reads.
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "soc/uart_periph.h"
|
||||
#include "test_apb_dport_access.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
|
||||
static void apb_access_loop_task(void *ignore);
|
||||
|
||||
static volatile bool apb_access_corrupt;
|
||||
static TaskHandle_t apb_task_handle;
|
||||
|
||||
void start_apb_access_loop(void)
|
||||
{
|
||||
apb_access_corrupt = false;
|
||||
xTaskCreatePinnedToCore(apb_access_loop_task, "accessAPB", 2048, NULL,
|
||||
UNITY_FREERTOS_PRIORITY - 1,
|
||||
&apb_task_handle, !UNITY_FREERTOS_CPU);
|
||||
}
|
||||
|
||||
void verify_apb_access_loop(void)
|
||||
{
|
||||
vTaskDelete(apb_task_handle);
|
||||
apb_task_handle = NULL;
|
||||
TEST_ASSERT_FALSE(apb_access_corrupt);
|
||||
printf("Verified no APB corruption from operations\n");
|
||||
}
|
||||
|
||||
static void apb_access_loop_task(void *ignore)
|
||||
{
|
||||
uint32_t initial = REG_READ(UART_DATE_REG(0));
|
||||
while(1) {
|
||||
if (REG_READ(UART_DATE_REG(0)) != initial) {
|
||||
apb_access_corrupt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else /*CONFIG_FREERTOS_UNICORE */
|
||||
|
||||
void start_apb_access_loop(void)
|
||||
{
|
||||
}
|
||||
|
||||
void verify_apb_access_loop(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
18
components/mbedtls/test/test_apb_dport_access.h
Normal file
18
components/mbedtls/test/test_apb_dport_access.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* Utility functions to test that APB access is still safe
|
||||
while the other CPU performs some set of DPORT accesses
|
||||
|
||||
(see ECO 3.10 and the standalone esp32 test_dport.c for more).
|
||||
*/
|
||||
|
||||
/* start_apb_access_loop() starts a task reading from APB in a loop on the non-Unity-test CPU.
|
||||
|
||||
Call this before doing something which involes DPORT reads.
|
||||
|
||||
Does nothing in unicore mode.
|
||||
*/
|
||||
void start_apb_access_loop(void);
|
||||
|
||||
/* verify_apb_access_loop() kills the task started by start_apb_access_loop()
|
||||
and verifies that none of the APB reads were corrupted by unsafe DPORT reads.
|
||||
*/
|
||||
void verify_apb_access_loop(void);
|
77
components/mbedtls/test/test_ecp.c
Normal file
77
components/mbedtls/test/test_ecp.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* mbedTLS Elliptic Curve functionality tests
|
||||
|
||||
Focus on testing functionality where we use ESP32 hardware
|
||||
accelerated crypto features.
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/ecdh.h>
|
||||
#include <mbedtls/ecdsa.h>
|
||||
#include <mbedtls/error.h>
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
/* Note: negative value here so that assert message prints a grep-able
|
||||
error hex value (mbedTLS uses -N for error codes) */
|
||||
#define TEST_ASSERT_MBEDTLS_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X))
|
||||
|
||||
TEST_CASE("mbedtls ECDH Generate Key", "[mbedtls]")
|
||||
{
|
||||
mbedtls_ecdh_context ctx;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
|
||||
mbedtls_ecdh_init(&ctx);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) );
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ecp_group_load(&ctx.grp, MBEDTLS_ECP_DP_CURVE25519) );
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ecdh_gen_public(&ctx.grp, &ctx.d, &ctx.Q,
|
||||
mbedtls_ctr_drbg_random, &ctr_drbg ) );
|
||||
|
||||
mbedtls_ecdh_free(&ctx);
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls ECP self-tests", "[mbedtls]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ecp_self_test(1));
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls ECP mul w/ koblitz", "[mbedtls]")
|
||||
{
|
||||
/* Test case code via https://github.com/espressif/esp-idf/issues/1556 */
|
||||
mbedtls_entropy_context ctxEntropy;
|
||||
mbedtls_ctr_drbg_context ctxRandom;
|
||||
mbedtls_ecdsa_context ctxECDSA;
|
||||
const char* pers = "myecdsa";
|
||||
|
||||
mbedtls_entropy_init(&ctxEntropy);
|
||||
mbedtls_ctr_drbg_init(&ctxRandom);
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ctr_drbg_seed(&ctxRandom, mbedtls_entropy_func, &ctxEntropy,
|
||||
(const unsigned char*) pers, strlen(pers)) );
|
||||
|
||||
mbedtls_ecdsa_init(&ctxECDSA);
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ecdsa_genkey(&ctxECDSA, MBEDTLS_ECP_DP_SECP256K1,
|
||||
mbedtls_ctr_drbg_random, &ctxRandom) );
|
||||
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_mul(&ctxECDSA.grp, &ctxECDSA.Q, &ctxECDSA.d, &ctxECDSA.grp.G,
|
||||
mbedtls_ctr_drbg_random, &ctxRandom) );
|
||||
|
||||
mbedtls_ecdsa_free(&ctxECDSA);
|
||||
mbedtls_ctr_drbg_free(&ctxRandom);
|
||||
mbedtls_entropy_free(&ctxEntropy);
|
||||
}
|
||||
|
45
components/mbedtls/test/test_mbedtls.c
Normal file
45
components/mbedtls/test/test_mbedtls.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* mbedTLS self-tests as unit tests
|
||||
|
||||
Focus on testing functionality where we use ESP32 hardware
|
||||
accelerated crypto features.
|
||||
|
||||
See also test_hwcrypto.c in esp32 component, which tests hardware crypto without mbedTLS.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "test_apb_dport_access.h"
|
||||
|
||||
TEST_CASE("mbedtls AES self-tests", "[aes]")
|
||||
{
|
||||
start_apb_access_loop();
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_aes_self_test(1), "AES self-tests should pass.");
|
||||
verify_apb_access_loop();
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls MPI self-tests", "[bignum]")
|
||||
{
|
||||
start_apb_access_loop();
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_mpi_self_test(1), "MPI self-tests should pass.");
|
||||
verify_apb_access_loop();
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls RSA self-tests", "[bignum]")
|
||||
{
|
||||
start_apb_access_loop();
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_rsa_self_test(1), "RSA self-tests should pass.");
|
||||
verify_apb_access_loop();
|
||||
}
|
||||
|
211
components/mbedtls/test/test_mbedtls_mpi.c
Normal file
211
components/mbedtls/test/test_mbedtls_mpi.c
Normal file
@ -0,0 +1,211 @@
|
||||
/* mbedTLS bignum (MPI) self-tests as unit tests
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define MBEDTLS_OK 0
|
||||
|
||||
/* Debugging function to print an MPI number to stdout. Happens to
|
||||
print output that can be copy-pasted directly into a Python shell.
|
||||
*/
|
||||
void mbedtls_mpi_printf(const char *name, const mbedtls_mpi *X)
|
||||
{
|
||||
static char buf[1024];
|
||||
size_t n;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
mbedtls_mpi_write_string(X, 16, buf, sizeof(buf)-1, &n);
|
||||
if(n) {
|
||||
printf("%s = 0x%s\n", name, buf);
|
||||
} else {
|
||||
printf("%s = TOOLONG\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert E = A * B */
|
||||
static void test_bignum_mult(const char *a_str, const char *b_str, const char *e_str, size_t mod_bits)
|
||||
{
|
||||
mbedtls_mpi A, B, X, E, M;
|
||||
char x_buf[1024] = { 0 };
|
||||
size_t x_buf_len = 0;
|
||||
|
||||
mbedtls_mpi_init(&A);
|
||||
mbedtls_mpi_init(&B);
|
||||
mbedtls_mpi_init(&X);
|
||||
mbedtls_mpi_init(&E);
|
||||
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&A, 16, a_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&B, 16, b_str));
|
||||
|
||||
/* E = A * B */
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&E, 16, e_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_mul_mpi(&X, &A, &B));
|
||||
|
||||
mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len);
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "mbedtls_mpi_mul_mpi result wrong");
|
||||
|
||||
/* if mod_bits arg is set, also do a esp_mpi_mul_mod() call */
|
||||
if (mod_bits > 0) {
|
||||
mbedtls_mpi_init(&M);
|
||||
for(int i = 0; i < mod_bits; i++) {
|
||||
mbedtls_mpi_set_bit(&M, i, 1);
|
||||
}
|
||||
|
||||
TEST_ASSERT_FALSE(esp_mpi_mul_mpi_mod(&X, &A, &B, &M));
|
||||
|
||||
mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len);
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "esp_mpi_mul_mpi_mod result wrong");
|
||||
|
||||
mbedtls_mpi_free(&M);
|
||||
}
|
||||
|
||||
|
||||
mbedtls_mpi_free(&A);
|
||||
mbedtls_mpi_free(&B);
|
||||
mbedtls_mpi_free(&X);
|
||||
mbedtls_mpi_free(&E);
|
||||
}
|
||||
|
||||
TEST_CASE("test MPI multiplication", "[bignum]")
|
||||
{
|
||||
/* Run some trivial numbers tests w/ various high modulo bit counts,
|
||||
should make no difference to the result
|
||||
*/
|
||||
for(int i = 512; i <= 4096; i+= 512) {
|
||||
test_bignum_mult("10", "100", "1000",
|
||||
i);
|
||||
}
|
||||
|
||||
test_bignum_mult("60006FA8D3E3BD746BE39B860FFAADB4F108E15CF2ED8F685FB0E86CC4CB107A488720B41C3F1E18550F00619CD3CA8442296ECB54D2F52ECEE5346D310195700000000",
|
||||
"BF474CA7",
|
||||
"047BB102CAF58A48D3D97E4231BC0B753051D8232B9B939A2A4E310F88E65FEFD7762FC2DE0E2BAD6AA51A391DFFABD120653A312E4998F42E2C03AA404EE63B67275BC100000000",
|
||||
1024);
|
||||
|
||||
test_bignum_mult("49493AC229831EC01EEB01EAF3BBEBC44768EADF9ABC30C87D1791F5E04245756ED4965361EC0599626884DF079B6B5738985CE76BD66FAA67E3AAAD60775D5C9D44C09FDF9E27C033696C007BE1C540D718CA148BA01FFA4A358541E9E9F02F72BE37AFAB037DAEA5E3669A770400D2F4A5DBBD83A83919D05E3DD64787BC80000000",
|
||||
"B878CC29",
|
||||
"34CF37013066D5BDA2C86CF1FE7BDA66604E0D55DAFF9864B6E727BFF5871012B0AB73D28D4E100BA1E4607AA2A247C912FDBC435C6BF7C5F8E00278AE1381B1E5F6E3D52D2CBE819F0D65CB37370666D156E7A7B1FD4698D8C9D3165FC8A83F9293C839521993619CCF8180E521300C4306206C9121D629754F1FCC7839BF6DFAF33080000000",
|
||||
3072);
|
||||
|
||||
test_bignum_mult("24BF6185468786FDD303083D25E64EFC66CA472BC44D253102F8B4A9D3BFA75091386C0077937FE33FA3252D28855837AE1B484A8A9A45F7EE8C0C634F9E8CDDF79C5CE07EE72C7F123142198164234CABB724CF78B8173B9F880FC86322407AF1FEDFDDE2BEB674CA15F3E81A1521E071513A1E85B5DFA031F21ECAE9A34D",
|
||||
"010001",
|
||||
"24BF8644A80CCD855A00DB402E2374E2B5C6ADF60B78E97E2829B7A288697B103888FD38E393F776BF8664D04DB280BD0652F665D2E4D0923483FAEF5C01DC7C847A547CDBC7AB663EB0544AC37DA4B0CF03D0869D878FF3B6C3AF5072EAA39D3279D1DCC29C9933808ABDFE0DFD3BF59331AB6FBFD46556119250BD086E36A34D",
|
||||
1536);
|
||||
|
||||
test_bignum_mult("-5D88B669C417EDD02213723546A906B7E9DA7683780E9B54856A2147467ADA316F8819D69486FC8056FE1E8EA7DEC5D5EF12340B95C4FC966F4B348D35893620",
|
||||
"9AE7FBC99546432DF71896FC239EADAEF38D18D2B2F0E2DD275AA977E2BF4411F5A3B2A5D33605AEBBCCBA7FEB9F2D2FA74206CEC169D74BF5A8C50D6F48EA08",
|
||||
"-38990016EB21810E3B5E6AEE339AEE72BB7CD629C4C9270A3D832701A2949BC82B2BE5A7F900C0C9937464699862821976095187D646884E8FBF01DE8C3442F3BC97B670AF573EFB74A9BBEBE4432EE74B0A83BBCDF59485D332B1FF49EB461A3A8B12C38FD72C7772D75EC6EBA5633199540C47678BD2F4ADEEA40830C2F100",
|
||||
2048);
|
||||
|
||||
|
||||
/* 1 << 2050 * 0X1234 */
|
||||
test_bignum_mult("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"1234",
|
||||
"48D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
3072);
|
||||
|
||||
/* multiply a 1178 bit number by a 2050 bit number */
|
||||
test_bignum_mult("AAAAAAAAAA75124938ABBECD0EEEEE333333333333333333333FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAABBBBBBBBBBBBBBBBBBBB000000000000000000000000000000000004988A5293848932948872398400000000000FFFFFFFFFFF0000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238",
|
||||
"390587293875124938ABBECD0EEEEE3333333333333333333333333333333399999888000AAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238478327400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003012111111111111111100000000000000000000000111111111111111111111111",
|
||||
"02603AF70D0421C1AD82CE623F28F70B128118D06D00C27D433EC25BA86E6105C3890A0B1973B8BE068CA68E159A21078785DDB37F94216FBF4AEC939958AF4B8CEA2A48895CECA87562FC846EAAE0C866AF9D41EEABFB1D579F5828E9666A15E2AF946F16A189B5C645872FDCA247D309AB0BCAFB0D112881186FCFFEDC87061B4AE4A375E9BBCF579A7BC87A8EAC8C6F66E107986FC603F920F5E1A0FD8C619D88D90066FFFC8F4DB77437EBD7E3BD7E398C4C01F93426E347E039DCA7B0A73C0C90A9C4271BB761ADFF88971D190CE5DA98EFC5D7390D33BC034908AF81D784A4D7F32D0902E0C5DABC706635D5A28FC0E3A364EDEB21E8E117041D0E4B51CA6F9684F434057E7FCF2AF6BD050334B1D11E043B0967154E57354B681161D3C618974D5A7E0385755B80B931AE9B59DD4402BAEC206F04B8440741B3C4CA6D9F7DAF0AE6B3BF1B24B76C2F12B9E9A7C50D32E2093608FC9A30CBD852329E64A9AE0BC3F513899EBFA28629C1DF38081FB8C6630408F70D7B9A37701ABA4176C8B7DCB8CC78BD7783B861A7FC50862E75191DB8",
|
||||
4096);
|
||||
}
|
||||
|
||||
static bool test_bignum_modexp(const char *z_str, const char *x_str, const char *y_str, const char *m_str, int ret_error)
|
||||
{
|
||||
mbedtls_mpi Z, X, Y, M;
|
||||
char z_buf[400] = { 0 };
|
||||
size_t z_buf_len = 0;
|
||||
bool fail = false;
|
||||
|
||||
printf("%s = (%s ^ %s) mod %s ret=%d ... ", z_str, x_str, y_str, m_str, ret_error);
|
||||
|
||||
mbedtls_mpi_init(&Z);
|
||||
mbedtls_mpi_init(&X);
|
||||
mbedtls_mpi_init(&Y);
|
||||
mbedtls_mpi_init(&M);
|
||||
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&X, 16, x_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&Y, 16, y_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&M, 16, m_str));
|
||||
|
||||
//mbedtls_mpi_printf("X", &X);
|
||||
//mbedtls_mpi_printf("X", &Y);
|
||||
//mbedtls_mpi_printf("M", &M);
|
||||
|
||||
/* Z = (X ^ Y) mod M */
|
||||
if (ret_error != mbedtls_mpi_exp_mod(&Z, &X, &Y, &M, NULL)) {
|
||||
fail = true;
|
||||
}
|
||||
|
||||
if (ret_error == MBEDTLS_OK) {
|
||||
mbedtls_mpi_write_string(&Z, 16, z_buf, sizeof(z_buf)-1, &z_buf_len);
|
||||
if (memcmp(z_str, z_buf, strlen(z_str)) != 0) {
|
||||
printf("\n Expected '%s' Was '%s' \n", z_str, z_buf);
|
||||
fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_mpi_free(&Z);
|
||||
mbedtls_mpi_free(&X);
|
||||
mbedtls_mpi_free(&Y);
|
||||
mbedtls_mpi_free(&M);
|
||||
|
||||
if (fail == true) {
|
||||
printf(" FAIL\n");
|
||||
} else {
|
||||
printf(" PASS\n");
|
||||
}
|
||||
return fail;
|
||||
}
|
||||
|
||||
TEST_CASE("test MPI modexp", "[bignum]")
|
||||
{
|
||||
bool test_error = false;
|
||||
printf("Z = (X ^ Y) mod M \n");
|
||||
// test_bignum_modexp(Z, X, Y, M, ret_error);
|
||||
test_error |= test_bignum_modexp("01000000", "1000", "2", "FFFFFFFF", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("014B5A90", "1234", "2", "FFFFFFF", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("01234321", "1111", "2", "FFFFFFFF", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("02", "5", "1", "3", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("22", "55", "1", "33", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("0222", "555", "1", "333", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("2222", "5555", "1", "3333", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("11", "5555", "1", "33", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("55", "1111", "1", "77", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("88", "1111", "2", "BB", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("01000000", "2", "128", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("0ABCDEF12345", "ABCDEF12345", "1", "FFFFFFFFFFFF", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("0ABCDE", "ABCDE", "1", "FFFFF", MBEDTLS_OK);
|
||||
|
||||
test_error |= test_bignum_modexp("04", "2", "2", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("04", "2", "-2", "9", MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
|
||||
test_error |= test_bignum_modexp("04", "2", "2", "-9", MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
|
||||
test_error |= test_bignum_modexp("04", "2", "-2", "-9", MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
|
||||
|
||||
test_error |= test_bignum_modexp("01", "2", "0", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("04", "2", "0", "0", MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
|
||||
test_error |= test_bignum_modexp("04", "2", "2", "0", MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
|
||||
test_error |= test_bignum_modexp("00", "0", "2", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("01", "0", "0", "9", MBEDTLS_OK);
|
||||
|
||||
test_error |= test_bignum_modexp("04", "-2", "2", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("01", "-2", "0", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("07", "-2", "7", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("07", "-2", "1", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("02", "2", "1", "9", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("01", "2", "0", "9", MBEDTLS_OK);
|
||||
|
||||
test_error |= test_bignum_modexp("05", "5", "7", "7", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("02", "-5", "7", "7", MBEDTLS_OK);
|
||||
test_error |= test_bignum_modexp("01", "-5", "7", "3", MBEDTLS_OK);
|
||||
|
||||
TEST_ASSERT_FALSE_MESSAGE(test_error, "mbedtls_mpi_exp_mod incorrect for some tests\n");
|
||||
}
|
||||
|
301
components/mbedtls/test/test_mbedtls_sha.c
Normal file
301
components/mbedtls/test/test_mbedtls_sha.c
Normal file
@ -0,0 +1,301 @@
|
||||
/* mbedTLS SHA unit tests
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "test_apb_dport_access.h"
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
|
||||
{
|
||||
start_apb_access_loop();
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha256_self_test(1), "SHA256 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
verify_apb_access_loop();
|
||||
}
|
||||
|
||||
static const unsigned char *one_hundred_as = (unsigned char *)
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
|
||||
static const unsigned char *one_hundred_bs = (unsigned char *)
|
||||
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
|
||||
static const uint8_t sha256_thousand_as[32] = {
|
||||
0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9, 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c,
|
||||
0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3 };
|
||||
|
||||
static const uint8_t sha256_thousand_bs[32] = {
|
||||
0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b
|
||||
};
|
||||
|
||||
static const uint8_t sha512_thousand_bs[64] = {
|
||||
0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d
|
||||
};
|
||||
|
||||
static const uint8_t sha384_thousand_bs[48] = {
|
||||
0x6d, 0xe5, 0xf5, 0x88, 0x57, 0x60, 0x83, 0xff, 0x7c, 0x94, 0x61, 0x5f, 0x8d, 0x96, 0xf2, 0x76, 0xd5, 0x3f, 0x77, 0x0c, 0x8e, 0xc1, 0xbf, 0xb6, 0x04, 0x27, 0xa4, 0xba, 0xea, 0x6c, 0x68, 0x44, 0xbd, 0xb0, 0x9c, 0xef, 0x6a, 0x09, 0x28, 0xe8, 0x1f, 0xfc, 0x95, 0x03, 0x69, 0x99, 0xab, 0x1a
|
||||
};
|
||||
|
||||
static const uint8_t sha1_thousand_as[20] = {
|
||||
0x29, 0x1e, 0x9a, 0x6c, 0x66, 0x99, 0x49, 0x49, 0xb5, 0x7b, 0xa5,
|
||||
0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba };
|
||||
|
||||
TEST_CASE("mbedtls SHA interleaving", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
mbedtls_sha512_context sha512_ctx;
|
||||
unsigned char sha1[20], sha256[32], sha512[64];
|
||||
|
||||
mbedtls_sha1_init(&sha1_ctx);
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
mbedtls_sha512_init(&sha512_ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts_ret(&sha1_ctx));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&sha512_ctx, false));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_update_ret(&sha1_ctx, one_hundred_as, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, one_hundred_as, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&sha512_ctx, one_hundred_bs, 100));
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish_ret(&sha1_ctx, sha1));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&sha512_ctx, sha512));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 calculation");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 calculation");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
|
||||
}
|
||||
|
||||
static xSemaphoreHandle done_sem;
|
||||
static void tskRunSHA1Test(void *pvParameters)
|
||||
{
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
unsigned char sha1[20];
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
mbedtls_sha1_init(&sha1_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts_ret(&sha1_ctx));
|
||||
for (int j = 0; j < 10; j++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_update_ret(&sha1_ctx, (unsigned char *)one_hundred_as, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish_ret(&sha1_ctx, sha1));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void tskRunSHA256Test(void *pvParameters)
|
||||
{
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
|
||||
for (int j = 0; j < 10; j++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, (unsigned char *)one_hundred_bs, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation");
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
#define SHA_TASK_STACK_SIZE (10*1024)
|
||||
|
||||
TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(4, 0);
|
||||
xTaskCreate(tskRunSHA1Test, "SHA1Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA1Test, "SHA1Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(!xSemaphoreTake(done_sem, 10000/portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
void tskRunSHASelftests(void *param)
|
||||
{
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if(mbedtls_sha1_self_test(1)) {
|
||||
printf("SHA1 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha256_self_test(1)) {
|
||||
printf("SHA256 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(2, 0);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
|
||||
const int TIMEOUT_MS = 20000;
|
||||
|
||||
for(int i = 0; i < 2; i++) {
|
||||
if(!xSemaphoreTake(done_sem, TIMEOUT_MS/portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
unsigned char sha512[64];
|
||||
|
||||
mbedtls_sha512_init(&ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&ctx, false));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
|
||||
}
|
||||
|
||||
mbedtls_sha512_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&clone, one_hundred_bs, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&ctx, sha512));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 original calculation");
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&clone, sha512));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA384 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
unsigned char sha384[48];
|
||||
|
||||
mbedtls_sha512_init(&ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&ctx, true));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
|
||||
}
|
||||
|
||||
mbedtls_sha512_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&clone, one_hundred_bs, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&ctx, sha384));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation");
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&clone, sha384));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_context clone;
|
||||
unsigned char sha256[64];
|
||||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&ctx, false));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&ctx, one_hundred_as, 100));
|
||||
}
|
||||
|
||||
mbedtls_sha256_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&ctx, one_hundred_as, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&clone, one_hundred_as, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&ctx, sha256));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 original calculation");
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&clone, sha256));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
mbedtls_sha256_context ctx;
|
||||
uint8_t result[32];
|
||||
int ret;
|
||||
bool done;
|
||||
} finalise_sha_param_t;
|
||||
|
||||
static void tskFinaliseSha(void *v_param)
|
||||
{
|
||||
finalise_sha_param_t *param = (finalise_sha_param_t *)v_param;
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(¶m->ctx, one_hundred_as, 100));
|
||||
}
|
||||
|
||||
param->ret = mbedtls_sha256_finish_ret(¶m->ctx, param->result);
|
||||
param->done = true;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA session passed between tasks" , "[mbedtls]")
|
||||
{
|
||||
finalise_sha_param_t param = { 0 };
|
||||
|
||||
mbedtls_sha256_init(¶m.ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(¶m.ctx, false));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(¶m.ctx, one_hundred_as, 100));
|
||||
}
|
||||
|
||||
// pass the SHA context off to a different task
|
||||
//
|
||||
// note: at the moment this doesn't crash even if a mutex semaphore is used as the
|
||||
// engine lock, but it can crash...
|
||||
xTaskCreate(tskFinaliseSha, "SHAFinalise", SHA_TASK_STACK_SIZE, ¶m, 3, NULL);
|
||||
|
||||
while (!param.done) {
|
||||
vTaskDelay(1);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, param.ret);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, param.result, 32, "SHA256 result from other task");
|
||||
}
|
240
components/mbedtls/test/test_rsa.c
Normal file
240
components/mbedtls/test/test_rsa.c
Normal file
@ -0,0 +1,240 @@
|
||||
/* mbedTLS RSA functionality tests
|
||||
|
||||
Focus on testing functionality where we use ESP32 hardware
|
||||
accelerated crypto features.
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* Taken from openssl s_client -connect api.gigafive.com:443 -showcerts
|
||||
*/
|
||||
static const char *rsa4096_cert = "-----BEGIN CERTIFICATE-----\n"\
|
||||
"MIIExzCCA6+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBkjELMAkGA1UEBhMCVVMx\n"\
|
||||
"CzAJBgNVBAgMAkNBMRQwEgYDVQQHDAtTYW50YSBDbGFyYTElMCMGA1UECgwcR2ln\n"\
|
||||
"YWZpdmUgVGVjaG5vbG9neSBQYXJ0bmVyczEZMBcGA1UEAwwQR2lnYWZpdmUgUm9v\n"\
|
||||
"dCBDQTEeMBwGCSqGSIb3DQEJARYPY2FAZ2lnYWZpdmUuY29tMB4XDTE2MDgyNzE2\n"\
|
||||
"NDYyM1oXDTI2MDgyNTE2NDYyM1owgZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD\n"\
|
||||
"QTEUMBIGA1UEBwwLU2FudGEgQ2xhcmExKTAnBgNVBAoMIEdpZ2FmaXZlIFRlY2hu\n"\
|
||||
"b2xvZ3kgUGFydG5lcnMgTExDMRkwFwYDVQQDDBBhcGkuZ2lnYWZpdmUuY29tMR8w\n"\
|
||||
"HQYJKoZIhvcNAQkBFhBjcmxAZ2lnYWZpdmUuY29tMIICIjANBgkqhkiG9w0BAQEF\n"\
|
||||
"AAOCAg8AMIICCgKCAgEAof82VrEpXMpsI/ddW6RLeTeSYtxiXZZkRbDKN6otYgEk\n"\
|
||||
"vA8yRbzei2cO2A/8+Erhe9beYLAMXWF+bjoUAFwnuIcbmufgHprOYzX/7CYXCsrH\n"\
|
||||
"LrJfVF6kvjCXy2W3xSvgh8ZgHNWnBGzl13tq19Fz8x0AhK5GQ9608oJCbnQjpVSI\n"\
|
||||
"lZDl3JVOifCeXf2c7nMhVOC/reTeto0Gbchs8Ox50WyojmfYbVjOQcA7f8p1eI+D\n"\
|
||||
"XUJK01cUGVu6/KarVArGHh5LsiyXOadbyeyOXPmjyrgarG3IIBeQSNECfJZPc/OW\n"\
|
||||
"lFszjU4YLDckI4x+tReiuFQbQPN5sDplcEldmZZm/8XD36ddvAaDds+SYlPXxDK7\n"\
|
||||
"7L8RBVUG2Ylc9YZf7RE6IMDmdQmsCZDX0VxySYEmzv5lnAx4mzzaXcgS+kHMOLyK\n"\
|
||||
"n9UxmpzwQoqqC9tMZqwRaeKW1njR1dSwQLqirBPfGCWKkpkpm7C3HEfeeLrasral\n"\
|
||||
"aPf6LAwN3A4ZKHa5Jmne7W+1eYS1aTXOAOLIPcXRAh1B80H+SusIdM9d6vk2YTIg\n"\
|
||||
"khwGQV3sgM6nIO5+T/8z141UEjWbtP7pb/u0+G9Cg7TwvRoO2UukxdvOwNto1G2e\n"\
|
||||
"J3rKB/JSYsYWnPHvvh9XR+55PZ4iCf9Rqw/IP82uyGipR9gxlHqN8WhMTj9tNEkC\n"\
|
||||
"AwEAAaMhMB8wHQYDVR0OBBYEFISCemcSriz1HFhRXluw9H+Bv9lEMA0GCSqGSIb3\n"\
|
||||
"DQEBCwUAA4IBAQCMetK0xe6Y/uZpb1ARh+hHYcHI3xI+IG4opWJeoB1gDh/xpNAW\n"\
|
||||
"j6t5MGbLoqNMBXbqL26hnKVspyvCxw7ebI5ZJgjtbrD1t+0D8yrgIZzr7AWGA9Hj\n"\
|
||||
"WIHqDHGDxwkmfjVVPmuO3l5RtJmL6KV6kVL2bOvVI6gECpFLddmOTtg+iXDfSw3x\n"\
|
||||
"0+ueMYKr8QLF+TCxfzQTHvTHvOJtcZHecc1n7PYbRmI2p7tV6RoBpV69oM6NAVUV\n"\
|
||||
"i2QoSxm0pYzDzavOaxwhEPHT34Tpg6fwXy1QokFD9OtxRFtdpTjL3bMWpatZE+ba\n"\
|
||||
"cjvvf0utMW5fNjTTxu1nnpuxZM3ifTCqZJ+9\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
/* Root cert from openssl s_client -connect google.com:443 -showcerts
|
||||
*/
|
||||
static const char *rsa2048_cert = "-----BEGIN CERTIFICATE-----\n"\
|
||||
"MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT\n"\
|
||||
"MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0\n"\
|
||||
"aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw\n"\
|
||||
"WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE\n"\
|
||||
"AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n"\
|
||||
"CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m\n"\
|
||||
"OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu\n"\
|
||||
"T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c\n"\
|
||||
"JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR\n"\
|
||||
"Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz\n"\
|
||||
"PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm\n"\
|
||||
"aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM\n"\
|
||||
"TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g\n"\
|
||||
"LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO\n"\
|
||||
"BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv\n"\
|
||||
"dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB\n"\
|
||||
"AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL\n"\
|
||||
"NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W\n"\
|
||||
"b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
/* Some random input bytes to public key encrypt */
|
||||
static const uint8_t pki_input[4096/8] = {
|
||||
0, 1, 4, 6, 7, 9, 33, 103, 49, 11, 56, 211, 67, 92 };
|
||||
|
||||
/* Result of an RSA4096 operation using cert's public key
|
||||
(raw PKI, no padding/etc) */
|
||||
static const uint8_t pki_rsa4096_output[] = {
|
||||
0x91, 0x87, 0xcd, 0x04, 0x80, 0x7c, 0x8b, 0x0b,
|
||||
0x0c, 0xc0, 0x38, 0x37, 0x7a, 0xe3, 0x2c, 0x94,
|
||||
0xea, 0xc4, 0xcb, 0x83, 0x2c, 0x77, 0x71, 0x14,
|
||||
0x11, 0x85, 0x16, 0x61, 0xd3, 0x64, 0x2a, 0x0f,
|
||||
0xf9, 0x6b, 0x45, 0x04, 0x66, 0x5d, 0x15, 0xf1,
|
||||
0xcf, 0x69, 0x77, 0x90, 0xb9, 0x41, 0x68, 0xa9,
|
||||
0xa6, 0xfd, 0x94, 0xdc, 0x6a, 0xce, 0xc7, 0xb6,
|
||||
0x41, 0xd9, 0x44, 0x3c, 0x02, 0xb6, 0xc7, 0x26,
|
||||
0xce, 0xec, 0x66, 0x21, 0xa8, 0xe8, 0xf4, 0xa9,
|
||||
0x33, 0x4a, 0x6c, 0x28, 0x0f, 0x50, 0x30, 0x32,
|
||||
0x28, 0x00, 0xbb, 0x2c, 0xc3, 0x44, 0x72, 0x31,
|
||||
0x93, 0xd4, 0xde, 0x29, 0x6b, 0xfa, 0x31, 0xfd,
|
||||
0x3a, 0x05, 0xc6, 0xb1, 0x28, 0x43, 0x57, 0x20,
|
||||
0xf7, 0xf8, 0x13, 0x0c, 0x4a, 0x80, 0x00, 0xab,
|
||||
0x1f, 0xe8, 0x88, 0xad, 0x56, 0xf2, 0xda, 0x5a,
|
||||
0x50, 0xe9, 0x02, 0x09, 0x21, 0x2a, 0xfc, 0x82,
|
||||
0x68, 0x34, 0xf9, 0x04, 0xa3, 0x25, 0xe1, 0x0f,
|
||||
0xa8, 0x77, 0x29, 0x94, 0xb6, 0x9d, 0x5a, 0x08,
|
||||
0x33, 0x8d, 0x27, 0x6a, 0xc0, 0x3b, 0xad, 0x91,
|
||||
0x8a, 0x83, 0xa9, 0x2e, 0x48, 0xcd, 0x67, 0xa3,
|
||||
0x3a, 0x35, 0x41, 0x85, 0xfa, 0x3f, 0x61, 0x1f,
|
||||
0x80, 0xeb, 0xcd, 0x5a, 0xc5, 0x14, 0x7b, 0xab,
|
||||
0x9c, 0x45, 0x11, 0xd2, 0x25, 0x9a, 0x16, 0xeb,
|
||||
0x9c, 0xfa, 0xbe, 0x73, 0x18, 0xbd, 0x25, 0x8e,
|
||||
0x99, 0x6d, 0xb3, 0xbc, 0xac, 0x2d, 0xa2, 0x53,
|
||||
0xe8, 0x7c, 0x38, 0x1b, 0x7a, 0x75, 0xff, 0x76,
|
||||
0x4f, 0x48, 0x5b, 0x39, 0x20, 0x5a, 0x7b, 0x82,
|
||||
0xd3, 0x33, 0x33, 0x2a, 0xab, 0x6a, 0x7a, 0x42,
|
||||
0x1d, 0x1f, 0xd1, 0x61, 0x58, 0xd7, 0x38, 0x52,
|
||||
0xdf, 0xb0, 0x61, 0x98, 0x63, 0xb7, 0xa1, 0x4e,
|
||||
0xdb, 0x9b, 0xcb, 0xb7, 0x85, 0xc4, 0x3e, 0x03,
|
||||
0xe5, 0x59, 0x50, 0x28, 0x5a, 0x4d, 0x7f, 0x53,
|
||||
0x2e, 0x99, 0x1d, 0x6d, 0x85, 0x27, 0x78, 0x34,
|
||||
0x5e, 0xae, 0xc9, 0x1b, 0x37, 0x96, 0xde, 0x40,
|
||||
0x87, 0x35, 0x3c, 0x1f, 0xe0, 0x8f, 0xfb, 0x3a,
|
||||
0x58, 0x0e, 0x60, 0xe9, 0x06, 0xbd, 0x83, 0x03,
|
||||
0x92, 0xde, 0x5e, 0x69, 0x28, 0xb1, 0x00, 0xeb,
|
||||
0x44, 0xca, 0x3c, 0x49, 0x03, 0x10, 0xa8, 0x84,
|
||||
0xa6, 0xbb, 0xd5, 0xda, 0x98, 0x8c, 0x6f, 0xa3,
|
||||
0x0f, 0x39, 0xf3, 0xa7, 0x7d, 0xd5, 0x3b, 0xe2,
|
||||
0x85, 0x12, 0xda, 0xa4, 0x4d, 0x80, 0x97, 0xcb,
|
||||
0x11, 0xe0, 0x89, 0x90, 0xff, 0x5b, 0x72, 0x19,
|
||||
0x59, 0xd1, 0x39, 0x23, 0x9f, 0xb0, 0x00, 0xe2,
|
||||
0x45, 0x72, 0xc6, 0x9a, 0xbc, 0xe1, 0xd1, 0x51,
|
||||
0x6b, 0x35, 0xd2, 0x49, 0xbf, 0xb6, 0xfe, 0xab,
|
||||
0x09, 0xf7, 0x9d, 0xa4, 0x6e, 0x69, 0xb6, 0xf9,
|
||||
0xde, 0xe3, 0x57, 0x0c, 0x1a, 0x96, 0xf1, 0xcc,
|
||||
0x1c, 0x92, 0xdb, 0x44, 0xf4, 0x45, 0xfa, 0x8f,
|
||||
0x87, 0xcf, 0xf4, 0xd2, 0xa1, 0xf8, 0x69, 0x18,
|
||||
0xcf, 0xdc, 0xa0, 0x1f, 0xb0, 0x26, 0xad, 0x81,
|
||||
0xab, 0xdf, 0x78, 0x18, 0xa2, 0x74, 0xba, 0x2f,
|
||||
0xec, 0x70, 0xa2, 0x1f, 0x56, 0xee, 0xff, 0xc9,
|
||||
0xfe, 0xb1, 0xe1, 0x9b, 0xea, 0x0e, 0x33, 0x14,
|
||||
0x5f, 0x6e, 0xca, 0xee, 0x02, 0x56, 0x5a, 0x67,
|
||||
0x42, 0x9a, 0xbf, 0x55, 0xc0, 0x0f, 0x8e, 0x01,
|
||||
0x67, 0x63, 0x6e, 0xd1, 0x57, 0xf7, 0xf1, 0xc6,
|
||||
0x92, 0x9e, 0xb5, 0x45, 0xe1, 0x50, 0x58, 0x94,
|
||||
0x20, 0x90, 0x6a, 0x29, 0x2d, 0x4b, 0xd1, 0xb5,
|
||||
0x68, 0x63, 0xb5, 0xe6, 0xd8, 0x6e, 0x84, 0x80,
|
||||
0xad, 0xe6, 0x03, 0x1e, 0x51, 0xc2, 0xa8, 0x6d,
|
||||
0x84, 0xec, 0x2d, 0x7c, 0x61, 0x02, 0xd1, 0xda,
|
||||
0xf5, 0x94, 0xfa, 0x2d, 0xa6, 0xed, 0x89, 0x6a,
|
||||
0x6a, 0xda, 0x07, 0x5d, 0x83, 0xfc, 0x43, 0x76,
|
||||
0x7c, 0xca, 0x8c, 0x00, 0xfc, 0xb9, 0x2c, 0x23,
|
||||
};
|
||||
|
||||
static const uint8_t pki_rsa2048_output[] = {
|
||||
0x47, 0x0b, 0xe5, 0x8a, 0xcd, 0x2f, 0x78, 0x07,
|
||||
0x69, 0x69, 0x70, 0xff, 0x81, 0xdf, 0x96, 0xf0,
|
||||
0xed, 0x82, 0x3a, 0x3d, 0x46, 0xab, 0xe9, 0xc3,
|
||||
0xb5, 0xd9, 0xca, 0xa2, 0x05, 0xa9, 0xf6, 0x6e,
|
||||
0xad, 0x6c, 0xe0, 0xd1, 0xa2, 0xb4, 0xf2, 0x78,
|
||||
0x4a, 0x93, 0xfc, 0x45, 0xe1, 0x9b, 0xdd, 0x62,
|
||||
0xf9, 0x66, 0x2a, 0x14, 0x38, 0x12, 0xb6, 0x50,
|
||||
0x0b, 0xe3, 0x53, 0x9c, 0x12, 0x56, 0xf1, 0xb7,
|
||||
0x83, 0xd5, 0xf3, 0x24, 0x81, 0xcc, 0x5a, 0xeb,
|
||||
0xec, 0xac, 0x68, 0xa8, 0x0c, 0xd7, 0x84, 0x7a,
|
||||
0xbb, 0x77, 0x7b, 0xd5, 0x5b, 0xcf, 0x7b, 0x25,
|
||||
0xd0, 0x75, 0x80, 0x21, 0x12, 0x97, 0x6b, 0xe1,
|
||||
0xb6, 0x51, 0x12, 0x52, 0x6e, 0x01, 0x92, 0xb7,
|
||||
0xcc, 0x70, 0x4b, 0x46, 0x11, 0x98, 0x5a, 0x84,
|
||||
0x1c, 0x90, 0x45, 0x0f, 0x15, 0x77, 0xdb, 0x79,
|
||||
0xe8, 0xff, 0x1f, 0xaa, 0x58, 0x95, 0xce, 0x3c,
|
||||
0x65, 0x0c, 0x66, 0x29, 0xe1, 0x9c, 0x41, 0xbb,
|
||||
0xde, 0x65, 0xb8, 0x29, 0x36, 0x94, 0xbd, 0x87,
|
||||
0x93, 0x39, 0xc5, 0xeb, 0x49, 0x21, 0xc1, 0xeb,
|
||||
0x48, 0xbd, 0x19, 0x13, 0x4d, 0x40, 0x90, 0x88,
|
||||
0xc6, 0x12, 0xd9, 0xf7, 0xdd, 0xc8, 0x4f, 0x89,
|
||||
0xc0, 0x91, 0xf8, 0xeb, 0xcf, 0xe3, 0x12, 0x17,
|
||||
0x88, 0x9c, 0x88, 0xf4, 0xf5, 0xae, 0xf4, 0x15,
|
||||
0xfe, 0x17, 0xf6, 0xa4, 0x74, 0x49, 0x02, 0x05,
|
||||
0x11, 0x3b, 0x92, 0x25, 0x39, 0x2c, 0x4b, 0x08,
|
||||
0x19, 0x76, 0x13, 0x8d, 0xf9, 0xda, 0xae, 0xdf,
|
||||
0x30, 0xda, 0xcc, 0xbb, 0x3f, 0xb9, 0xb0, 0xd6,
|
||||
0x5c, 0x78, 0x4b, 0x2b, 0x35, 0x51, 0x17, 0x48,
|
||||
0xf5, 0xd4, 0x39, 0x7e, 0x05, 0x83, 0x68, 0x86,
|
||||
0x44, 0x5f, 0x56, 0x1d, 0x2c, 0x53, 0xd3, 0x64,
|
||||
0x3a, 0xb2, 0x0c, 0x4a, 0x85, 0xd6, 0x5b, 0x7e,
|
||||
0xf9, 0xe9, 0x50, 0x29, 0x5d, 0x4f, 0xcc, 0xc9,
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(pki_rsa2048_output) == 2048/8, "rsa2048 output is wrong size");
|
||||
_Static_assert(sizeof(pki_rsa4096_output) == 4096/8, "rsa4096 output is wrong size");
|
||||
|
||||
static void test_cert(const char *cert, const uint8_t *expected_output, size_t output_len);
|
||||
|
||||
TEST_CASE("mbedtls RSA4096 cert", "[mbedtls]")
|
||||
{
|
||||
|
||||
test_cert(rsa4096_cert, pki_rsa4096_output, 4096/8);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls RSA2048 cert", "[mbedtls]")
|
||||
{
|
||||
test_cert(rsa2048_cert, pki_rsa2048_output, 2048/8);
|
||||
}
|
||||
|
||||
static void test_cert(const char *cert, const uint8_t *expected_output, size_t output_len)
|
||||
{
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_rsa_context *rsa;
|
||||
char buf[output_len];
|
||||
|
||||
bzero(buf, output_len);
|
||||
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16_MESSAGE(0,
|
||||
-mbedtls_x509_crt_parse(&crt,
|
||||
(const uint8_t *)cert,
|
||||
strlen(cert)+1),
|
||||
"parse cert");
|
||||
|
||||
rsa = mbedtls_pk_rsa(crt.pk);
|
||||
TEST_ASSERT_NOT_NULL(rsa);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16_MESSAGE(0,
|
||||
-mbedtls_rsa_check_pubkey(rsa),
|
||||
"check cert pubkey");
|
||||
|
||||
mbedtls_x509_crt_info(buf, sizeof(buf), "", &crt);
|
||||
puts(buf);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16_MESSAGE(0,
|
||||
-mbedtls_rsa_public(rsa, pki_input, (uint8_t *)buf),
|
||||
"RSA PK operation");
|
||||
|
||||
/*
|
||||
// Dump buffer for debugging
|
||||
for(int i = 0; i < output_len; i++) {
|
||||
printf("0x%02x, ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_output, buf, output_len);
|
||||
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
}
|
Reference in New Issue
Block a user