diff --git a/.gitignore b/.gitignore index 84fdff138..ab9cda89b 100644 --- a/.gitignore +++ b/.gitignore @@ -418,3 +418,6 @@ user_settings_asm.h # auto-created CMake backups **/CMakeLists.txt.old + +# MagicCrypto (ARIA Cipher) +MagicCrypto diff --git a/cmake/functions.cmake b/cmake/functions.cmake index e77991ea1..213488838 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -79,6 +79,9 @@ function(generate_build_flags) set(BUILD_INTEL_ASM ${WOLFSSL_INTEL_ASM} PARENT_SCOPE) set(BUILD_AFALG ${WOLFSSL_AFALG} PARENT_SCOPE) set(BUILD_DEVCRYPTO ${WOLFSSL_DEVCRYPTO} PARENT_SCOPE) + if(HAVE_ARIA OR WOLFSSL_USER_SETTINGS) + set(BUILD_ARIA "yes" PARENT_SCOPE) + endif() if(WOLFSSL_CAMELLIA OR WOLFSSL_USER_SETTINGS) set(BUILD_CAMELLIA "yes" PARENT_SCOPE) endif() diff --git a/configure.ac b/configure.ac index 46e9c1103..b18985853 100644 --- a/configure.ac +++ b/configure.ac @@ -2512,6 +2512,31 @@ fi ] ) +AC_ARG_ENABLE([aria], + [AS_HELP_STRING([--enable-aria],[Enable wolfSSL support for ARIA (default: disabled)])], + [ ENABLED_ARIA=$enableval ], + [ ENABLED_ARIA=no ] + ) +if test "$ENABLED_ARIA" = "yes" +then + ARIA_DIR=MagicCrypto + # Enable dependency + ENABLED_OPENSSLEXTRA="yes" + CFLAGS="$CFLAGS -I$ARIA_DIR/include" + AM_CFLAGS="$AM_CFLAGS -DHAVE_ARIA -DOPENSSL_EXTRA" + AM_LDFLAGS="$AM_LDFLAGS -L$ARIA_DIR/lib -lMagicCrypto" + build_pwd="$(pwd)" + headers="mcapi_error.h mcapi_type.h mcapi.h" + for header in $headers + do + AC_CHECK_HEADER([$header], [], [ + AC_MSG_ERROR([Error including $header. Please put the MagicCrypto library in $build_pwd.]) + ], [ + extern int dummy_int_to_make_compiler_happy; + ]) + done +fi + AC_ARG_ENABLE([caam], [AS_HELP_STRING([--enable-caam],[Enable wolfSSL support for CAAM (default: disabled)])], [ ENABLED_CAAM=$enableval ], @@ -8779,6 +8804,7 @@ AM_CONDITIONAL([BUILD_DTLS_CID],[test "x$ENABLED_DTLS_CID" = "xyes"]) AM_CONDITIONAL([BUILD_HPKE],[test "x$ENABLED_HPKE" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_DTLS],[test "x$ENABLED_DTLS" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_MAXQ10XX],[test "x$ENABLED_MAXQ10XX" = "xyes"]) +AM_CONDITIONAL([BUILD_ARIA],[test "x$ENABLED_ARIA" = "xyes"]) if test "$ENABLED_REPRODUCIBLE_BUILD" != "yes" && (test "$ax_enable_debug" = "yes" || @@ -9089,6 +9115,7 @@ echo " * AES-CTR: $ENABLED_AESCTR" echo " * AES-CFB: $ENABLED_AESCFB" echo " * AES-OFB: $ENABLED_AESOFB" echo " * AES-SIV: $ENABLED_AESSIV" +echo " * ARIA: $ENABLED_ARIA" echo " * DES3: $ENABLED_DES3" echo " * Camellia: $ENABLED_CAMELLIA" echo " * SM4-ECB: $ENABLED_SM4_ECB" diff --git a/examples/server/server.c b/examples/server/server.c index 6d05e4779..379323d2c 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -2824,7 +2824,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #ifdef WOLFSSL_SNIFFER if (cipherList == NULL && version < 4) { /* static RSA or static ECC cipher suites */ - const char* staticCipherList = "AES128-SHA:ECDH-ECDSA-AES128-SHA"; + const char* staticCipherList = "AES128-SHA:ECDH-ECDSA-AES128-SHA" + #if defined(HAVE_ARIA) + ":ECDHE-ECDSA-ARIA128-GCM-SHA256:ECDHE-ECDSA-ARIA256-GCM-SHA384" + #endif + ; if (SSL_CTX_set_cipher_list(ctx, staticCipherList) != WOLFSSL_SUCCESS) { err_sys_ex(runWithErrors, "server can't set cipher list 3"); } diff --git a/scripts/sniffer-gen.sh b/scripts/sniffer-gen.sh index c58352a36..8e395d18f 100755 --- a/scripts/sniffer-gen.sh +++ b/scripts/sniffer-gen.sh @@ -1,4 +1,5 @@ #!/bin/bash +#set -x # Run this script from the wolfSSL root if [ ! -f wolfssl/ssl.h ]; then @@ -6,93 +7,87 @@ if [ ! -f wolfssl/ssl.h ]; then exit 1 fi +server_pid=0 +tcpdump_pid=0 + +cleanup() { + if [ "$server_pid" -ne 0 ]; then kill $server_pid; server_pid=0; fi + if [ "$tcpdump_pid" -ne 0 ]; then sleep 1; kill -15 $tcpdump_pid; tcpdump_pid=0; fi +} +trap cleanup EXIT INT TERM HUP + +set -o pipefail +prepend() { # Usage: cmd 2>&1 | prepend "sometext " + while read line; do echo "${1}${line}"; done +} + +run_test() { # Usage: run_test [serverArgs [clientArgs]] + echo "Running test $1" + CIPHER=$1 + if [ "$CIPHER" != "" ]; then + CIPHER="-l $CIPHER" + fi + stdbuf -oL -eL ./examples/server/server -i -x $CIPHER $2 2>&1 | prepend "[server] " & + server_pid=$! + ((server_pid--)) # Get the first PID in the pipe + sleep 0.1 + stdbuf -oL -eL ./examples/client/client $CIPHER $3 2>&1 | prepend "[client] " + RET=$? + if [ "$RET" != 0 ]; then + echo "Error in test: $RET" + exit $RET + fi + kill $server_pid; server_pid=0 + echo "Test passed: $1" +} + run_sequence() { - if [ "$1" == "dh" ] || [ "$1" == "ecc" ]; then - # TLS v1.3 - ./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256 - - ./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 - - ./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 + if [ "$1" == "tls13-dh" ] || [ "$1" == "tls13-ecc" ]; then # TLS v1.3 + run_test "TLS13-AES128-GCM-SHA256" "-v 4" "-v 4" + run_test "TLS13-AES256-GCM-SHA384" "-v 4" "-v 4" + run_test "TLS13-CHACHA20-POLY1305-SHA256" "-v 4" "-v 4" + elif [ "$1" == "tls12" ]; then # TLS v1.2 + run_test "ECDHE-ECDSA-AES128-GCM-SHA256" "-v 3 -A ./certs/ca-ecc-cert.pem -k ./certs/ecc-key.pem -c ./certs/intermediate/server-chain-ecc.pem -V" "-v 3 -A ./certs/ca-ecc-cert.pem -k ./certs/ecc-client-key.pem -c ./certs/intermediate/client-chain-ecc.pem -C" + run_test "ECDHE-ECDSA-AES256-GCM-SHA384" "-v 3 -A ./certs/ca-ecc-cert.pem -k ./certs/ecc-key.pem -c ./certs/intermediate/server-chain-ecc.pem -V" "-v 3 -A ./certs/ca-ecc-cert.pem -k ./certs/ecc-client-key.pem -c ./certs/intermediate/client-chain-ecc.pem -C" + elif [ "$1" == "tls13-dh-resume" ] || [ "$1" == "tls13-ecc-resume" ]; then # TLS v1.3 Resumption + run_test "TLS13-AES128-GCM-SHA256" "-v 4 -r" "-v 4 -r" + run_test "TLS13-AES256-GCM-SHA384" "-v 4 -r" "-v 4 -r" + run_test "TLS13-CHACHA20-POLY1305-SHA256" "-v 4 -r" "-v 4 -r" + elif [ "$1" == "tls13-x25519" ]; then # TLS v1.3 + run_test "TLS13-AES128-GCM-SHA256" "-v 4 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem" "-v 4 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem" + run_test "TLS13-AES256-GCM-SHA384" "-v 4 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem" "-v 4 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem" + run_test "TLS13-CHACHA20-POLY1305-SHA256" "-v 4 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem" "-v 4 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem" + elif [ "$1" == "tls13-x25519-resume" ]; then # TLS v1.3 x25519 Resumption + run_test "TLS13-AES128-GCM-SHA256" "-v 4 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem" "-v 4 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem" + run_test "TLS13-AES256-GCM-SHA384" "-v 4 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem" "-v 4 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem" + run_test "TLS13-CHACHA20-POLY1305-SHA256" "-v 4 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem" "-v 4 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem" + elif [ "$1" == "tls13-hrr" ]; then # TLS v1.3 Hello Retry Request + run_test "" "-v 4 -g" "-v 4 -J" + else + echo "Invalid test" + exit -1 fi - if [ "$1" == "dh-resume" ] || [ "$1" == "ecc-resume" ]; then - # TLS v1.3 Resumption - ./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 -r & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256 -r - - ./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 -r & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -r - - ./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r - fi - - if [ "$1" == "x25519" ]; then - # TLS v1.3 - ./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem - - ./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem - - ./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem - fi - # Run: with x25519_resume - if [ "$1" == "x25519-resume" ]; then - # TLS v1.3 Resumption - ./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem - - ./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem - - ./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem & - sleep 0.1 - ./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem - fi - - # TLS v1.3 Hello Retry Request - if [ "$1" == "hrr" ]; then - # TLS v1.3 Hello Retry Request - ./examples/server/server -v 4 -i -x -g & - server_pid=$! - sleep 0.1 - ./examples/client/client -v 4 -J - kill $server_pid - fi - sleep 1 } run_capture(){ - echo -e "\nconfiguring and building wolfssl..." + echo -e "\nconfiguring and building wolfssl ($1)..." ./configure --enable-sniffer $2 1>/dev/null || exit $? make 1>/dev/null || exit $? echo "starting capture" - tcpdump -i lo0 -nn port 11111 -w ./scripts/sniffer-tls13-$1.pcap & + tcpdump -i lo -n port 11111 -w ./scripts/sniffer-${1}.pcap -U & tcpdump_pid=$! run_sequence $1 - kill $tcpdump_pid + sleep 1 + kill -15 $tcpdump_pid; tcpdump_pid=0 } -run_capture "ecc" "" -run_capture "ecc-resume" "--enable-session-ticket" -run_capture "dh" "--disable-ecc" -run_capture "dh-resume" "--disable-ecc --enable-session-ticket" -run_capture "x25519" "--enable-curve25519 --disable-dh --disable-ecc" -run_capture "x25519-resume" "--enable-curve25519 --disable-dh --disable-ecc --enable-session-ticket" -run_capture "hrr" "--disable-dh CFLAGS=-DWOLFSSL_SNIFFER_WATCH" +run_capture "tls12" "" +run_capture "tls13-ecc" "" +run_capture "tls13-ecc-resume" "--enable-session-ticket" +run_capture "tls13-dh" "--disable-ecc" +run_capture "tls13-dh-resume" "--disable-ecc --enable-session-ticket" +run_capture "tls13-x25519" "--enable-curve25519 --disable-dh --disable-ecc" +run_capture "tls13-x25519-resume" "--enable-curve25519 --disable-dh --disable-ecc --enable-session-ticket" +run_capture "tls13-hrr" "--disable-dh CFLAGS=-DWOLFSSL_SNIFFER_WATCH" + +echo "Tests passed in $SECONDS seconds" diff --git a/src/include.am b/src/include.am index 174be8483..727505327 100644 --- a/src/include.am +++ b/src/include.am @@ -790,3 +790,8 @@ endif !BUILD_CRYPTONLY endif !BUILD_FIPS_RAND + +if BUILD_ARIA +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/aria/aria-crypt.c +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/aria/aria-cryptocb.c +endif diff --git a/src/internal.c b/src/internal.c index 13360f93a..980f16aea 100644 --- a/src/internal.c +++ b/src/internal.c @@ -128,6 +128,11 @@ #include #endif +#ifdef HAVE_ARIA + /* included to get ARIA devId value */ + #include +#endif + #if defined(DEBUG_WOLFSSL) || defined(SHOW_SECRETS) || \ defined(CHACHA_AEAD_TEST) || defined(WOLFSSL_SESSION_EXPORT_DEBUG) #ifndef NO_STDIO_FILESYSTEM @@ -2302,6 +2307,8 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifdef WOLFSSL_QNX_CAAM /* default to try using CAAM when built */ ctx->devId = WOLFSSL_CAAM_DEVID; +#elif defined(HAVE_ARIA) && defined(WOLF_CRYPTO_CB) + ctx->devId = WOLFSSL_ARIA_DEVID; #else ctx->devId = INVALID_DEVID; #endif @@ -2707,6 +2714,10 @@ void InitCiphers(WOLFSSL* ssl) ssl->encrypt.aes = NULL; ssl->decrypt.aes = NULL; #endif +#ifdef HAVE_ARIA + ssl->encrypt.aria = NULL; + ssl->decrypt.aria = NULL; +#endif #ifdef HAVE_CAMELLIA ssl->encrypt.cam = NULL; ssl->decrypt.cam = NULL; @@ -2750,9 +2761,8 @@ void FreeCiphers(WOLFSSL* ssl) XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif -#if defined(BUILD_AES) || defined(BUILD_AESGCM) /* See: InitKeys() in keys.c - * on addition of BUILD_AESGCM - * check (enc->aes, dec->aes) */ +#if defined(BUILD_AES) || defined(BUILD_AESGCM) || defined(HAVE_ARIA) + /* See: InitKeys() in keys.c on addition of BUILD_AESGCM check (enc->aes, dec->aes) */ wc_AesFree(ssl->encrypt.aes); wc_AesFree(ssl->decrypt.aes); XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER); @@ -2764,7 +2774,7 @@ void FreeCiphers(WOLFSSL* ssl) XFREE(ssl->encrypt.sm4, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->decrypt.sm4, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif -#if (defined(BUILD_AESGCM) || defined(BUILD_AESCCM)) && \ +#if (defined(BUILD_AESGCM) || defined(BUILD_AESCCM) || defined(HAVE_ARIA)) && \ !defined(WOLFSSL_NO_TLS12) XFREE(ssl->decrypt.additional, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->encrypt.additional, ssl->heap, DYNAMIC_TYPE_CIPHER); @@ -2773,6 +2783,12 @@ void FreeCiphers(WOLFSSL* ssl) XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif +#ifdef HAVE_ARIA + wc_AriaFreeCrypt(ssl->encrypt.aria); + wc_AriaFreeCrypt(ssl->decrypt.aria); + XFREE(ssl->encrypt.aria, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->decrypt.aria, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif #ifdef HAVE_CAMELLIA XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER); @@ -3355,6 +3371,20 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, } #endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 + if (tls1_2 && haveECC) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384; + } +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 + if (tls1_2 && haveECC) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256; + } +#endif + #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 if (tls1_2 && haveDH && havePSK) { suites->suites[idx++] = CIPHER_BYTE; @@ -11370,15 +11400,23 @@ static int CipherRequires(byte first, byte second, int requirement) #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #endif /* !NO_RSA */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM : - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 : - case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : - if (requirement == REQUIRES_ECC) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; +#ifdef HAVE_ARIA + case TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 : + case TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 : + if (requirement == REQUIRES_ECC) + return 1; + break; +#endif /* HAVE_ARIA */ + +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + case TLS_ECDHE_ECDSA_WITH_AES_128_CCM : + case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 : + case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : + if (requirement == REQUIRES_ECC) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 : case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : @@ -17850,6 +17888,58 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, break; #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #ifdef HAVE_ARIA + case wolfssl_aria_gcm: + { + const byte* additionalSrc = input - 5; + byte *outBuf = NULL; + XMEMSET(ssl->encrypt.additional, 0, AEAD_AUTH_DATA_SZ); + + /* sequence number field is 64-bits */ + WriteSEQ(ssl, CUR_ORDER, ssl->encrypt.additional); + + /* Store the type, version. Unfortunately, they are in + * the input buffer ahead of the plaintext. */ + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + additionalSrc -= DTLS_HANDSHAKE_EXTRA; + } + #endif + XMEMCPY(ssl->encrypt.additional + AEAD_TYPE_OFFSET, + additionalSrc, 3); + + /* Store the length of the plain text minus the explicit + * IV length minus the authentication tag size. */ + c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->encrypt.additional + AEAD_LEN_OFFSET); + XMEMCPY(ssl->encrypt.nonce, + ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ); + XMEMCPY(ssl->encrypt.nonce + AESGCM_IMP_IV_SZ, + ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ); + outBuf = (byte*)XMALLOC(sz - AESGCM_EXP_IV_SZ, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (outBuf == NULL) { + ret = MEMORY_ERROR; + break; + } + ret = wc_AriaEncrypt(ssl->encrypt.aria, outBuf, + (byte*) input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->encrypt.nonce, AESGCM_NONCE_SZ, + ssl->encrypt.additional, AEAD_AUTH_DATA_SZ, + out + sz - ssl->specs.aead_mac_size, + ssl->specs.aead_mac_size + ); + if (ret != 0) + break; + XMEMCPY(out, + ssl->encrypt.nonce + AESGCM_IMP_IV_SZ, AESGCM_EXP_IV_SZ); + XMEMCPY(out + AESGCM_EXP_IV_SZ,outBuf,sz - AESGCM_EXP_IV_SZ); + XFREE(outBuf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + break; + } + #endif + #ifdef HAVE_CAMELLIA case wolfssl_camellia: ret = wc_CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz); @@ -18008,11 +18098,12 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx); #endif - #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) + #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) /* make sure AES GCM/CCM memory is allocated */ /* free for these happens in FreeCiphers */ if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm || - ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) { + ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm || + ssl->specs.bulk_cipher_algorithm == wolfssl_aria_gcm) { /* make sure auth iv and auth are allocated */ if (ssl->encrypt.additional == NULL) ssl->encrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, @@ -18032,7 +18123,7 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, return MEMORY_E; } } - #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #endif /* BUILD_AESGCM || HAVE_AESCCM || HAVE_ARIA */ #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) /* make sure SM4 GCM/CCM memory is allocated */ @@ -18096,9 +18187,10 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, sizeof(ssl->encrypt.sanityCheck)); #endif - #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) + #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm || - ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) + ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm || + ssl->specs.bulk_cipher_algorithm == wolfssl_aria_gcm) { /* finalize authentication cipher */ #if !defined(NO_PUBLIC_GCM_SET_IV) && \ @@ -18109,7 +18201,7 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, if (ssl->encrypt.nonce) ForceZero(ssl->encrypt.nonce, AESGCM_NONCE_SZ); } - #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #endif /* BUILD_AESGCM || HAVE_AESCCM || HAVE_ARIA */ #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) if (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_ccm || ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_gcm) @@ -18276,6 +18368,55 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, break; #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #ifdef HAVE_ARIA + case wolfssl_aria_gcm: + { + byte *outBuf = NULL; + XMEMSET(ssl->decrypt.additional, 0, AEAD_AUTH_DATA_SZ); + + /* sequence number field is 64-bits */ + WriteSEQ(ssl, PEER_ORDER, ssl->decrypt.additional); + + ssl->decrypt.additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; + ssl->decrypt.additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; + ssl->decrypt.additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; + + c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->decrypt.additional + AEAD_LEN_OFFSET); + + #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) + if (ssl->options.dtls && IsDtlsMsgSCRKeys(ssl)) + XMEMCPY(ssl->decrypt.nonce, + ssl->secure_renegotiation->tmp_keys.aead_dec_imp_IV, + AESGCM_IMP_IV_SZ); + else + #endif + XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, + AESGCM_IMP_IV_SZ); + XMEMCPY(ssl->decrypt.nonce + AESGCM_IMP_IV_SZ, input, + AESGCM_EXP_IV_SZ); + outBuf = (byte*)XMALLOC(sz - AESGCM_EXP_IV_SZ, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (outBuf == NULL) { + ret = MEMORY_ERROR; + break; + } + ret = wc_AriaDecrypt(ssl->decrypt.aria, outBuf, + (byte *)input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->decrypt.nonce, AESGCM_NONCE_SZ, + ssl->decrypt.additional, AEAD_AUTH_DATA_SZ, + (byte *)input + sz - ssl->specs.aead_mac_size, + ssl->specs.aead_mac_size + ); + XMEMCPY(plain + AESGCM_EXP_IV_SZ, + outBuf, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size); + XFREE(outBuf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + break; + } + #endif /* HAVE_ARIA */ + #ifdef HAVE_CAMELLIA case wolfssl_camellia: ret = wc_CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz); @@ -18427,11 +18568,12 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) return DECRYPT_ERROR; } - #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) + #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) /* make sure AES GCM/CCM memory is allocated */ /* free for these happens in FreeCiphers */ if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm || - ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) { + ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm || + ssl->specs.bulk_cipher_algorithm == wolfssl_aria_gcm) { /* make sure auth iv and auth are allocated */ if (ssl->decrypt.additional == NULL) ssl->decrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, @@ -18451,7 +18593,7 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) return MEMORY_E; } } - #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #endif /* BUILD_AESGCM || HAVE_AESCCM || HAVE_ARIA */ #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) /* make sure SM4 GCM/CCM memory is allocated */ @@ -18525,7 +18667,7 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) FALL_THROUGH; case CIPHER_STATE_END: { - #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) + #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) /* make sure AES GCM/CCM nonce is cleared */ if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm || ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) { @@ -18537,7 +18679,7 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) WOLFSSL_ERROR_VERBOSE(ret); } } - #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #endif /* BUILD_AESGCM || HAVE_AESCCM || HAVE_ARIA */ #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) /* make sure SM4 GCM/CCM nonce is cleared */ if (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_ccm || @@ -24773,6 +24915,14 @@ static const CipherSuiteInfo cipher_names[] = SUITE_INFO("EDH-RSA-DES-CBC3-SHA","TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",CIPHER_BYTE,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLSv1_MINOR, SSLv3_MAJOR), #endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 + SUITE_INFO("ECDHE-ECDSA-ARIA128-GCM-SHA256","TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR), +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 + SUITE_INFO("ECDHE-ECDSA-ARIA256-GCM-SHA384","TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384",ECC_BYTE,TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, TLSv1_2_MINOR, SSLv3_MAJOR), +#endif + #ifdef BUILD_WDM_WITH_NULL_SHA256 SUITE_INFO("WDM-NULL-SHA256","WDM_WITH_NULL_SHA256",CIPHER_BYTE,WDM_WITH_NULL_SHA256, TLSv1_3_MINOR, SSLv3_MAJOR) #endif @@ -24972,6 +25122,14 @@ const char* GetCipherEncStr(char n[][MAX_SEGMENT_SZ]) { (XSTRCMP(n[2],"AES") == 0 && XSTRCMP(n[3],"256") == 0)) encStr = "AES(256)"; +#ifdef HAVE_ARIA + else if ((XSTRCMP(n[0],"ARIA256") == 0) || + (XSTRCMP(n[2],"ARIA256") == 0)) + encStr = "ARIA(256)"; + else if ((XSTRCMP(n[0],"ARIA128") == 0) || + (XSTRCMP(n[2],"ARIA128") == 0)) + encStr = "ARIA(128)"; +#endif else if ((XSTRCMP(n[0],"CAMELLIA256") == 0) || (XSTRCMP(n[2],"CAMELLIA256") == 0)) encStr = "CAMELLIA(256)"; diff --git a/src/keys.c b/src/keys.c index e240faa60..ce9e036e3 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1019,6 +1019,42 @@ int GetCipherSpec(word16 side, byte cipherSuite0, byte cipherSuite, break; #endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 + case TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 : + specs->bulk_cipher_algorithm = wolfssl_aria_gcm; + specs->cipher_type = aead; + specs->mac_algorithm = sha256_mac; + specs->kea = ecc_diffie_hellman_kea; + specs->sig_algo = ecc_dsa_sa_algo; + specs->hash_size = WC_SHA256_DIGEST_SIZE; + specs->pad_size = PAD_SHA; + specs->static_ecdh = 0; + specs->key_size = ARIA_128_KEY_SIZE; + specs->block_size = ARIA_BLOCK_SIZE; + specs->iv_size = AESGCM_IMP_IV_SZ; + specs->aead_mac_size = ARIA_GCM_AUTH_SZ; + + break; +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 + case TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 : + specs->bulk_cipher_algorithm = wolfssl_aria_gcm; + specs->cipher_type = aead; + specs->mac_algorithm = sha384_mac; + specs->kea = ecc_diffie_hellman_kea; + specs->sig_algo = ecc_dsa_sa_algo; + specs->hash_size = WC_SHA384_DIGEST_SIZE; + specs->pad_size = PAD_SHA; + specs->static_ecdh = 0; + specs->key_size = ARIA_256_KEY_SIZE; + specs->block_size = ARIA_BLOCK_SIZE; + specs->iv_size = AESGCM_IMP_IV_SZ; + specs->aead_mac_size = ARIA_GCM_AUTH_SZ; + + break; +#endif + #endif /* HAVE_ECC */ #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8 @@ -2829,6 +2865,106 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, } #endif /* HAVE_AESCCM */ +#ifdef HAVE_ARIA + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 16) /* AES_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for AES + #endif + + if (specs->bulk_cipher_algorithm == wolfssl_aria_gcm) { + int ret = 0; + MC_ALGID algo; + + switch(specs->key_size) { + case ARIA_128_KEY_SIZE: + algo = MC_ALGID_ARIA_128BITKEY; + break; + case ARIA_192_KEY_SIZE: + algo = MC_ALGID_ARIA_192BITKEY; + break; + case ARIA_256_KEY_SIZE: + algo = MC_ALGID_ARIA_256BITKEY; + break; + default: + return WOLFSSL_NOT_IMPLEMENTED; /* This should never happen */ + } + + if (enc) { + if (enc->aria == NULL) { + enc->aria = (wc_Aria*)XMALLOC(sizeof(wc_Aria), heap, DYNAMIC_TYPE_CIPHER); + if (enc->aria == NULL) + return MEMORY_E; + } else { + wc_AriaFreeCrypt(enc->aria); + } + + XMEMSET(enc->aria, 0, sizeof(wc_Aria)); + if (wc_AriaInitCrypt(enc->aria, algo) != 0) { + WOLFSSL_MSG("AriaInit failed in SetKeys"); + return ASYNC_INIT_E; + } + } + if (dec) { + if (dec->aria == NULL) { + dec->aria = (wc_Aria*)XMALLOC(sizeof(wc_Aria), heap, DYNAMIC_TYPE_CIPHER); + if (dec->aria == NULL) + return MEMORY_E; + } else { + wc_AriaFreeCrypt(dec->aria); + } + + XMEMSET(dec->aria, 0, sizeof(wc_Aria)); + if (wc_AriaInitCrypt(dec->aria, algo) != 0) { + WOLFSSL_MSG("AriaInit failed in SetKeys"); + return ASYNC_INIT_E; + } + } + + if (side == WOLFSSL_CLIENT_END) { + if (enc) { + ret = wc_AriaSetKey(enc->aria, keys->client_write_key); + if (ret != 0) return ret; + XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, + AEAD_MAX_IMP_SZ); + if (!tls13) { + ret = wc_AriaGcmSetIV(enc->aria, AESGCM_NONCE_SZ, + keys->client_write_IV, AESGCM_IMP_IV_SZ, rng); + if (ret != 0) return ret; + } + } + if (dec) { + ret = wc_AriaSetKey(dec->aria, keys->server_write_key); + if (ret != 0) return ret; + XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV, + AEAD_MAX_IMP_SZ); + } + } + else { + if (enc) { + ret = wc_AriaSetKey(enc->aria, keys->server_write_key); + if (ret != 0) return ret; + XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, + AEAD_MAX_IMP_SZ); + if (!tls13) { + ret = wc_AriaGcmSetIV(enc->aria, AESGCM_NONCE_SZ, + keys->server_write_IV, AESGCM_IMP_IV_SZ, rng); + if (ret != 0) return ret; + } + } + if (dec) { + ret = wc_AriaSetKey(dec->aria, keys->client_write_key); + if (ret != 0) return ret; + XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV, + AEAD_MAX_IMP_SZ); + } + } + if (enc) + enc->setup = 1; + if (dec) + dec->setup = 1; + } +#endif /* HAVE_ARIA */ + #ifdef HAVE_CAMELLIA /* check that buffer sizes are sufficient */ #if (MAX_WRITE_IV_SZ < 16) /* CAMELLIA_IV_SIZE */ diff --git a/src/sniffer.c b/src/sniffer.c index 54cca10e0..93681e804 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -4761,6 +4761,18 @@ static int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, break; #endif /* HAVE_AESGCM || HAVE_AESCCM */ + #ifdef HAVE_ARIA + case wolfssl_aria_gcm: + ret = wc_AriaDecrypt(ssl->decrypt.aria, + plain, + (byte *)input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->decrypt.nonce, AESGCM_NONCE_SZ, + ssl->decrypt.additional, ssl->specs.aead_mac_size, + NULL, 0); + break; + #endif + #ifdef HAVE_CAMELLIA case wolfssl_camellia: ret = wc_CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz); diff --git a/src/ssl.c b/src/ssl.c index 917f47f65..c1d232c7d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -22690,6 +22690,16 @@ static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size) encStr = "CHACHA20/POLY1305(256)"; break; #endif +#ifdef HAVE_ARIA + case wolfssl_aria_gcm: + if (key_size == 128) + encStr = "Aria(128)"; + else if (key_size == 256) + encStr = "Aria(256)"; + else + encStr = "Aria(?)"; + break; +#endif #ifdef HAVE_CAMELLIA case wolfssl_camellia: if (key_size == 128) @@ -29761,7 +29771,7 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) return obj_info->sName; } } - WOLFSSL_MSG("SN not found"); + WOLFSSL_MSG_EX("SN not found (nid:%d)",n); return NULL; } @@ -36603,6 +36613,15 @@ int wolfSSL_RAND_poll(void) #endif /* WOLFSSL_AES_XTS */ #endif /* NO_AES */ +#ifdef HAVE_ARIA + case ARIA_128_GCM_TYPE : + case ARIA_192_GCM_TYPE : + case ARIA_256_GCM_TYPE : + WOLFSSL_MSG("ARIA GCM"); + XMEMCPY(ctx->iv, &ctx->cipher.aria.nonce, ARIA_BLOCK_SIZE); + break; +#endif /* HAVE_ARIA */ + #ifndef NO_DES3 case DES_CBC_TYPE : WOLFSSL_MSG("DES CBC"); @@ -36725,6 +36744,15 @@ int wolfSSL_RAND_poll(void) #endif /* NO_AES */ +#ifdef HAVE_ARIA + case ARIA_128_GCM_TYPE : + case ARIA_192_GCM_TYPE : + case ARIA_256_GCM_TYPE : + WOLFSSL_MSG("ARIA GCM"); + XMEMCPY(&ctx->cipher.aria.nonce, ctx->iv, ARIA_BLOCK_SIZE); + break; +#endif /* HAVE_ARIA */ + #ifndef NO_DES3 case DES_CBC_TYPE : WOLFSSL_MSG("DES CBC"); diff --git a/tests/api.c b/tests/api.c index 2e0c906eb..885d4a684 100644 --- a/tests/api.c +++ b/tests/api.c @@ -51342,6 +51342,141 @@ static int test_wolfssl_EVP_aes_gcm(void) return EXPECT_RESULT(); } +static int test_wolfssl_EVP_aria_gcm(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(HAVE_ARIA) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + + /* A 256 bit key, AES_128 will use the first 128 bit*/ + byte *key = (byte*)"01234567890123456789012345678901"; + /* A 128 bit IV */ + byte *iv = (byte*)"0123456789012345"; + int ivSz = ARIA_BLOCK_SIZE; + /* Message to be encrypted */ + int plaintxtSz = 40; + byte plaintxt[WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(plaintxtSz)]; + XMEMCPY(plaintxt,"for things to change you have to change",plaintxtSz); + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[ARIA_BLOCK_SIZE] = {0}; + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(plaintxtSz)]; + byte decryptedtxt[plaintxtSz]; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + #define TEST_ARIA_GCM_COUNT 6 + EVP_CIPHER_CTX en[TEST_ARIA_GCM_COUNT]; + EVP_CIPHER_CTX de[TEST_ARIA_GCM_COUNT]; + + for (i = 0; i < TEST_ARIA_GCM_COUNT; i++) { + + EVP_CIPHER_CTX_init(&en[i]); + switch (i) { + case 0: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_128_gcm(), NULL, key, iv)); + break; + case 1: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_192_gcm(), NULL, key, iv)); + break; + case 2: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_256_gcm(), NULL, key, iv)); + break; + case 3: + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_128_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + break; + case 4: + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_192_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + break; + case 5: + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_256_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + break; + } + XMEMSET(ciphertxt,0,sizeof(ciphertxt)); + AssertIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, plaintxtSz)); + ciphertxtSz = len; + AssertIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + AssertIntNE(0, XMEMCMP(plaintxt, ciphertxt, plaintxtSz)); + ciphertxtSz += len; + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG, ARIA_BLOCK_SIZE, tag)); + AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1); + + EVP_CIPHER_CTX_init(&de[i]); + switch (i) { + case 0: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_128_gcm(), NULL, key, iv)); + break; + case 1: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_192_gcm(), NULL, key, iv)); + break; + case 2: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_256_gcm(), NULL, key, iv)); + break; + case 3: + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_128_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + break; + case 4: + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_192_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + break; + case 5: + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_256_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + break; + } + XMEMSET(decryptedtxt,0,sizeof(decryptedtxt)); + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz)); + decryptedtxtSz = len; + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, ARIA_BLOCK_SIZE, tag)); + AssertIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + AssertIntEQ(plaintxtSz, decryptedtxtSz); + AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + XMEMSET(decryptedtxt,0,sizeof(decryptedtxt)); + /* modify tag*/ + tag[AES_BLOCK_SIZE-1]+=0xBB; + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, ARIA_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz)); + AssertIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + AssertIntEQ(0, len); + AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); + } + + res = TEST_RES_CHECK(1); +#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */ + return res; +} + static int test_wolfssl_EVP_aes_ccm_zeroLen(void) { EXPECT_DECLS; @@ -62889,7 +63024,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_AES_ecb_encrypt), TEST_DECL(test_wolfSSL_AES_cbc_encrypt), TEST_DECL(test_wolfSSL_CRYPTO_cts128), - + TEST_DECL(test_wolfssl_EVP_aria_gcm), TEST_DECL(test_wolfSSL_OCSP_id_get0_info), TEST_DECL(test_wolfSSL_i2d_OCSP_CERTID), TEST_DECL(test_wolfSSL_d2i_OCSP_CERTID), diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 76a975a57..1d84002d9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -32955,6 +32955,12 @@ int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen) return wc_BuildEccKeyDer(key, output, &inLen, 0, 1); } +/* Write only private ecc key to DER format, + * length on success else < 0 */ +int wc_EccPrivateKeyToDerNoCurve(ecc_key* key, byte* output, word32 inLen) +{ + return wc_BuildEccKeyDer(key, output, &inLen, 0, 0); +} #ifdef HAVE_PKCS8 diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 13edcc49e..7b56fe812 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -34,6 +34,10 @@ #include #include +#ifdef HAVE_ARIA + #include +#endif + #ifdef WOLFSSL_CAAM #include #endif @@ -1337,6 +1341,8 @@ int wc_CryptoCb_DefaultDevID(void) /* conditional macro selection based on build */ #ifdef WOLFSSL_CAAM_DEVID ret = WOLFSSL_CAAM_DEVID; +#elif defined(HAVE_ARIA) + ret = WOLFSSL_ARIA_DEVID; #else ret = INVALID_DEVID; #endif diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 390bc0191..0fc7b85d7 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -47,7 +47,6 @@ #include #include - static const struct s_ent { const enum wc_HashType macType; const int nid; @@ -237,6 +236,13 @@ static const struct s_ent { #endif #endif +#ifdef HAVE_ARIA + #include + static const char EVP_ARIA_128_GCM[] = "ARIA-128-GCM"; + static const char EVP_ARIA_192_GCM[] = "ARIA-192-GCM"; + static const char EVP_ARIA_256_GCM[] = "ARIA-256-GCM"; +#endif + #ifndef NO_DES3 static const char EVP_DES_CBC[] = "DES-CBC"; static const char EVP_DES_ECB[] = "DES-ECB"; @@ -859,6 +865,69 @@ static int wolfSSL_EVP_CipherUpdate_CCM(WOLFSSL_EVP_CIPHER_CTX *ctx, } #endif /* HAVE_AESCCM || WOLFSSL_SM4_CCM */ +#if defined(HAVE_ARIA) +static int wolfSSL_EVP_CipherUpdate_AriaGCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx, + const unsigned char *in, int inl) +{ + if (in && inl > 0) { + byte* tmp = (byte*)XREALLOC(ctx->authIn, + ctx->authInSz + inl, NULL, DYNAMIC_TYPE_OPENSSL); + if (tmp) { + ctx->authIn = tmp; + XMEMCPY(ctx->authIn + ctx->authInSz, in, inl); + ctx->authInSz += inl; + } + else { + WOLFSSL_MSG("realloc error"); + return MEMORY_E; + } + } + return 0; +} + +static int wolfSSL_EVP_CipherUpdate_AriaGCM(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int ret = 0; + + *outl = inl; + if (out) { + /* Buffer input for one-shot API */ + if (inl > 0) { + byte* tmp; + int size = ctx->authBufferLen + inl; + if (ctx->enc == 0) { /* Append extra space for the tag */ + size = WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(size); + } + tmp = (byte*)XREALLOC(ctx->authBuffer, + size, NULL, + DYNAMIC_TYPE_OPENSSL); + if (tmp) { + XMEMCPY(tmp + ctx->authBufferLen, in, inl); + ctx->authBufferLen += inl; + ctx->authBuffer = tmp; + *outl = 0; + } + else { + ret = MEMORY_E; + } + } + } + else { + ret = wolfSSL_EVP_CipherUpdate_AriaGCM_AAD(ctx, in, inl); + } + + if (ret != 0) { + *outl = 0; + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} +#endif /* HAVE_ARIA */ + + /* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, @@ -900,6 +969,13 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, * additional auth data */ return wolfSSL_EVP_CipherUpdate_CCM(ctx, out, outl, in, inl); #endif /* !defined(NO_AES) && defined(HAVE_AESCCM) */ +#if defined(HAVE_ARIA) + case ARIA_128_GCM_TYPE: + case ARIA_192_GCM_TYPE: + case ARIA_256_GCM_TYPE: + /* if out == NULL, in/inl contains the additional auth data */ + return wolfSSL_EVP_CipherUpdate_AriaGCM(ctx, out, outl, in, inl); +#endif /* defined(HAVE_ARIA) */ #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) case CHACHA20_POLY1305_TYPE: if (out == NULL) { @@ -1231,6 +1307,61 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, break; #endif /* HAVE_AESCCM && ((!HAVE_FIPS && !HAVE_SELFTEST) || * HAVE_FIPS_VERSION >= 2 */ +#if defined(HAVE_ARIA) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \ + || FIPS_VERSION_GE(2,0)) + case ARIA_128_GCM_TYPE: + case ARIA_192_GCM_TYPE: + case ARIA_256_GCM_TYPE: + if ((ctx->authBuffer && ctx->authBufferLen > 0) + || (ctx->authBufferLen == 0)) { + if (ctx->enc) + ret = wc_AriaEncrypt(&ctx->cipher.aria, out, + ctx->authBuffer, ctx->authBufferLen, + ctx->iv, ctx->ivSz, ctx->authIn, ctx->authInSz, + ctx->authTag, ctx->authTagSz); + else + ret = wc_AriaDecrypt(&ctx->cipher.aria, out, + ctx->authBuffer, ctx->authBufferLen, + ctx->iv, ctx->ivSz, ctx->authIn, ctx->authInSz, + ctx->authTag, ctx->authTagSz); + + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + *outl = ctx->authBufferLen; + } + else { + ret = WOLFSSL_FAILURE; + *outl = 0; + } + + XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL); + ctx->authBuffer = NULL; + ctx->authBufferLen = 0; + + if (ctx->authIncIv) { + IncCtr((byte*)ctx->cipher.aria.nonce, + ctx->cipher.aria.nonceSz); + ctx->authIncIv = 0; + } + } + else { + *outl = 0; + } + if (ret == WOLFSSL_SUCCESS) { + if (ctx->authIncIv) { + ctx->authIncIv = 0; + } + else { + /* Clear IV, since IV reuse is not recommended for AES GCM. */ + XMEMSET(ctx->iv, 0, ARIA_BLOCK_SIZE); + } + if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) { + ret = WOLFSSL_FAILURE; + } + } + break; +#endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) || + * HAVE_FIPS_VERSION >= 2 */ #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) case CHACHA20_POLY1305_TYPE: if (wc_ChaCha20Poly1305_Final(&ctx->cipher.chachaPoly, @@ -1569,6 +1700,11 @@ int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx) case AES_128_XTS_TYPE: case AES_256_XTS_TYPE: #endif +#if defined(HAVE_ARIA) + case ARIA_128_GCM_TYPE: + case ARIA_192_GCM_TYPE: + case ARIA_256_GCM_TYPE: +#endif case AES_128_ECB_TYPE: case AES_192_ECB_TYPE: @@ -1751,6 +1887,14 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) #endif #endif #endif /* !NO_AES */ +#if defined(HAVE_ARIA) + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_ARIA_128_GCM)) + return ARIA_128_GCM_TYPE; + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_ARIA_192_GCM)) + return ARIA_192_GCM_TYPE; + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_ARIA_256_GCM)) + return ARIA_256_GCM_TYPE; +#endif /* HAVE_ARIA */ #ifndef NO_RC4 else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_ARC4)) @@ -1857,6 +2001,12 @@ int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher) case ARC4_TYPE: return 1; #endif +#if defined(HAVE_ARIA) + case ARIA_128_GCM_TYPE: + case ARIA_192_GCM_TYPE: + case ARIA_256_GCM_TYPE: + return 1; +#endif #ifndef NO_DES3 case DES_CBC_TYPE: return 8; @@ -1959,6 +2109,13 @@ unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher) case AES_256_ECB_TYPE: return WOLFSSL_EVP_CIPH_ECB_MODE; #endif /* !NO_AES */ + #if defined(HAVE_ARIA) + case ARIA_128_GCM_TYPE: + case ARIA_192_GCM_TYPE: + case ARIA_256_GCM_TYPE: + return WOLFSSL_EVP_CIPH_GCM_MODE | + WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER; + #endif #ifndef NO_DES3 case DES_CBC_TYPE: case DES_EDE3_CBC_TYPE: @@ -4718,6 +4875,12 @@ static const struct cipher{ #endif #endif +#ifdef HAVE_ARIA + {ARIA_128_GCM_TYPE, EVP_ARIA_128_GCM, NID_aria_128_gcm}, + {ARIA_192_GCM_TYPE, EVP_ARIA_192_GCM, NID_aria_192_gcm}, + {ARIA_256_GCM_TYPE, EVP_ARIA_256_GCM, NID_aria_256_gcm}, +#endif + #ifndef NO_DES3 {DES_CBC_TYPE, EVP_DES_CBC, NID_des_cbc}, {DES_ECB_TYPE, EVP_DES_ECB, NID_des_ecb}, @@ -4862,6 +5025,14 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name) #endif #endif #endif +#ifdef HAVE_ARIA + {EVP_ARIA_128_GCM, "aria-128-gcm"}, + {EVP_ARIA_128_GCM, "id-aria128-GCM"}, + {EVP_ARIA_192_GCM, "aria-192-gcm"}, + {EVP_ARIA_192_GCM, "id-aria192-GCM"}, + {EVP_ARIA_256_GCM, "aria-256-gcm"}, + {EVP_ARIA_256_GCM, "id-aria256-GCM"}, +#endif #ifdef WOLFSSL_SM4_EBC {EVP_SM4_ECB, "sm4-ecb"}, #endif @@ -4999,6 +5170,15 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) #endif #endif +#ifdef HAVE_ARIA + case NID_aria_128_gcm: + return wolfSSL_EVP_aria_128_gcm(); + case NID_aria_192_gcm: + return wolfSSL_EVP_aria_192_gcm(); + case NID_aria_256_gcm: + return wolfSSL_EVP_aria_256_gcm(); +#endif + #ifndef NO_DES3 case NID_des_cbc: return wolfSSL_EVP_des_cbc(); @@ -5476,6 +5656,24 @@ void wolfSSL_EVP_init(void) #endif /* HAVE_AES_ECB */ #endif /* NO_AES */ +#ifdef HAVE_ARIA + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aria_128_gcm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aria_128_gcm"); + return EVP_ARIA_128_GCM; + } + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aria_192_gcm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aria_192_gcm"); + return EVP_ARIA_192_GCM; + } + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aria_256_gcm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aria_256_gcm"); + return EVP_ARIA_256_GCM; + } +#endif /* HAVE_ARIA */ + #ifndef NO_DES3 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void) { @@ -5607,7 +5805,7 @@ void wolfSSL_EVP_init(void) case EVP_CTRL_SET_KEY_LENGTH: ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg); break; -#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) || \ defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) || \ (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) case EVP_CTRL_AEAD_SET_IVLEN: @@ -5832,7 +6030,7 @@ void wolfSSL_EVP_init(void) } break; #endif /* HAVE_AESGCM || HAVE_AESCCM || WOLFSSL_SM4_GCM || WOLFSSL_SM4_CCM || - * (HAVE_CHACHA && HAVE_POLY1305) */ + * HAVE_ARIA || (HAVE_CHACHA && HAVE_POLY1305) */ default: WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled"); break; @@ -5843,10 +6041,12 @@ void wolfSSL_EVP_init(void) /* WOLFSSL_SUCCESS on ok */ int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx) { + int ret = WOLFSSL_SUCCESS; WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_cleanup"); if (ctx) { #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + switch (ctx->cipherType) { #if (defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)) || \ defined(HAVE_AESCCM) || \ defined(HAVE_AESCBC) || \ @@ -5856,7 +6056,6 @@ void wolfSSL_EVP_init(void) defined(HAVE_AES_OFB) || \ defined(WOLFSSL_AES_XTS) - switch (ctx->cipherType) { #if defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM) case AES_128_GCM_TYPE: case AES_192_GCM_TYPE: @@ -5903,9 +6102,23 @@ void wolfSSL_EVP_init(void) case AES_256_XTS_TYPE: #endif wc_AesFree(&ctx->cipher.aes); + break; +#endif /* AES */ + #ifdef HAVE_ARIA + case ARIA_128_GCM_TYPE: + case ARIA_192_GCM_TYPE: + case ARIA_256_GCM_TYPE: + { + int result = wc_AriaFreeCrypt(&ctx->cipher.aria); + if (result != 0) { + WOLFSSL_MSG("wc_AriaFreeCrypt failure"); + ret = result; + } + } + break; + #endif } -#endif /* AES */ #endif /* not FIPS or FIPS v2+ */ #ifdef WOLFSSL_SM4 @@ -5938,7 +6151,7 @@ void wolfSSL_EVP_init(void) } #endif ctx->keyLen = 0; -#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) || \ defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) if (ctx->authBuffer) { XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL); @@ -5955,7 +6168,7 @@ void wolfSSL_EVP_init(void) #endif } - return WOLFSSL_SUCCESS; + return ret; } /* Permanent stub for Qt compilation. */ @@ -6383,6 +6596,86 @@ void wolfSSL_EVP_init(void) #endif /* HAVE_AESCCM && ((!HAVE_FIPS && !HAVE_SELFTEST) || * HAVE_FIPS_VERSION >= 2 */ +#if defined(HAVE_ARIA) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \ + || FIPS_VERSION_GE(2,0)) + static int EvpCipherInitAriaGCM(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + const byte* key, const byte* iv, int enc) + { + int ret = WOLFSSL_SUCCESS; + + if (ctx->cipherType == ARIA_128_GCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_ARIA_128_GCM))) { + WOLFSSL_MSG("EVP_ARIA_128_GCM"); + ctx->cipherType = ARIA_128_GCM_TYPE; + ctx->keyLen = ARIA_128_KEY_SIZE; + } else if (ctx->cipherType == ARIA_192_GCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_ARIA_192_GCM))) { + WOLFSSL_MSG("EVP_ARIA_192_GCM"); + ctx->cipherType = ARIA_192_GCM_TYPE; + ctx->keyLen = ARIA_192_KEY_SIZE; + } else if (ctx->cipherType == ARIA_256_GCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_ARIA_256_GCM))) { + WOLFSSL_MSG("EVP_ARIA_256_GCM"); + ctx->cipherType = ARIA_256_GCM_TYPE; + ctx->keyLen = ARIA_256_KEY_SIZE; + } else { + WOLFSSL_MSG("Unrecognized cipher type"); + return WOLFSSL_FAILURE; + } + + if (ctx->authIn) { + XFREE(ctx->authIn, NULL, DYNAMIC_TYPE_OPENSSL); + ctx->authIn = NULL; + } + ctx->authInSz = 0; + + ctx->block_size = AES_BLOCK_SIZE; + ctx->authTagSz = AES_BLOCK_SIZE; + if (ctx->ivSz == 0) { + ctx->ivSz = GCM_NONCE_MID_SZ; + } + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE | + WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER; + if (enc == 0 || enc == 1) { + ctx->enc = enc ? 1 : 0; + } + + switch(ctx->cipherType) { + case ARIA_128_GCM_TYPE: + ret = wc_AriaInitCrypt(&ctx->cipher.aria, MC_ALGID_ARIA_128BITKEY); + break; + case ARIA_192_GCM_TYPE: + ret = wc_AriaInitCrypt(&ctx->cipher.aria, MC_ALGID_ARIA_192BITKEY); + break; + case ARIA_256_GCM_TYPE: + ret = wc_AriaInitCrypt(&ctx->cipher.aria, MC_ALGID_ARIA_256BITKEY); + break; + default: + WOLFSSL_MSG("Not implemented cipherType"); + return WOLFSSL_NOT_IMPLEMENTED; /* This should never happen */ + } + if (ret != 0) { + WOLFSSL_MSG(MC_GetErrorString(ret)); + WOLFSSL_MSG(MC_GetError(ctx->cipher.aria.hSession)); + return WOLFSSL_FAILURE; + } + + if (key && wc_AriaSetKey(&ctx->cipher.aria, (byte *)key)) { + WOLFSSL_MSG("wc_AriaSetKey() failed"); + return WOLFSSL_FAILURE; + } + if (iv && wc_AriaGcmSetExtIV(&ctx->cipher.aria, iv, ctx->ivSz)) { + WOLFSSL_MSG("wc_AriaGcmSetIV() failed"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; + } +#endif /* HAVE_ARIA && ((!HAVE_FIPS && !HAVE_SELFTEST) || + * HAVE_FIPS_VERSION >= 2 */ + /* return WOLFSSL_SUCCESS on ok, 0 on failure to match API compatibility */ int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx, const WOLFSSL_EVP_CIPHER* type, const byte* key, @@ -7063,6 +7356,23 @@ void wolfSSL_EVP_init(void) #endif /* WOLFSSL_AES_256 */ #endif /* HAVE_AES_XTS */ #endif /* NO_AES */ + #if defined(HAVE_ARIA) + if (ctx->cipherType == ARIA_128_GCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_ARIA_128_GCM)) + || ctx->cipherType == ARIA_192_GCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_ARIA_192_GCM)) + || ctx->cipherType == ARIA_256_GCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_ARIA_256_GCM)) + ) { + if (EvpCipherInitAriaGCM(ctx, type, key, iv, enc) + != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + } + #endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) || + * HAVE_FIPS_VERSION >= 2 */ + + #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) if (ctx->cipherType == CHACHA20_POLY1305_TYPE || (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_CHACHA20_POLY1305))) { @@ -7440,6 +7750,15 @@ void wolfSSL_EVP_init(void) #endif /* NO_AES */ +#ifdef HAVE_ARIA + case ARIA_128_GCM_TYPE : + return NID_aria_128_gcm; + case ARIA_192_GCM_TYPE : + return NID_aria_192_gcm; + case ARIA_256_GCM_TYPE : + return NID_aria_256_gcm; +#endif + #ifndef NO_DES3 case DES_CBC_TYPE : return NID_des_cbc; @@ -7608,6 +7927,11 @@ void wolfSSL_EVP_init(void) ctx->cipherType != AES_192_CCM_TYPE && ctx->cipherType != AES_256_CCM_TYPE #endif + #ifdef HAVE_ARIA + && ctx->cipherType != ARIA_128_GCM_TYPE && + ctx->cipherType != ARIA_192_GCM_TYPE && + ctx->cipherType != ARIA_256_GCM_TYPE + #endif #ifdef WOLFSSL_SM4_GCM && ctx->cipherType != SM4_GCM_TYPE #endif @@ -7752,6 +8076,26 @@ void wolfSSL_EVP_init(void) #endif /* WOLFSSL_AES_COUNTER */ #endif /* NO_AES */ +#if defined(HAVE_ARIA) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \ + || FIPS_VERSION_GE(2,0)) + case ARIA_128_GCM_TYPE : + case ARIA_192_GCM_TYPE : + case ARIA_256_GCM_TYPE : + WOLFSSL_MSG("ARIA GCM"); + if (ctx->enc) { + ret = wc_AriaEncrypt(&ctx->cipher.aria, dst, src, len, + ctx->iv, ctx->ivSz, NULL, 0, + ctx->authTag, ctx->authTagSz); + } + else { + ret = wc_AriaDecrypt(&ctx->cipher.aria, dst, src, len, + ctx->iv, ctx->ivSz, NULL, 0, + ctx->authTag, ctx->authTagSz); + } + break; +#endif /* HAVE_ARIA&& ((!HAVE_FIPS && !HAVE_SELFTEST) || + * HAVE_FIPS_VERSION >= 2 */ + #ifndef NO_DES3 case DES_CBC_TYPE : WOLFSSL_MSG("DES CBC"); @@ -8770,6 +9114,16 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx) WOLFSSL_MSG("AES XTS"); return AES_BLOCK_SIZE; #endif /* WOLFSSL_AES_XTS */ +#ifdef HAVE_ARIA + case ARIA_128_GCM_TYPE : + case ARIA_192_GCM_TYPE : + case ARIA_256_GCM_TYPE : + WOLFSSL_MSG("ARIA GCM"); + if (ctx->ivSz != 0) { + return ctx->ivSz; + } + return GCM_NONCE_MID_SZ; +#endif #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) case CHACHA20_POLY1305_TYPE: WOLFSSL_MSG("CHACHA20 POLY1305"); @@ -8896,6 +9250,14 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher) #endif /* WOLFSSL_AES_XTS */ #endif +#ifdef HAVE_ARIA + if (XSTRCMP(name, EVP_ARIA_128_GCM) == 0) + return GCM_NONCE_MID_SZ; + if (XSTRCMP(name, EVP_ARIA_192_GCM) == 0) + return GCM_NONCE_MID_SZ; + if (XSTRCMP(name, EVP_ARIA_256_GCM) == 0) + return GCM_NONCE_MID_SZ; +#endif /* HAVE_ARIA */ #ifndef NO_DES3 if ((XSTRCMP(name, EVP_DES_CBC) == 0) || diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 608b93568..ed4145734 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -63,6 +63,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/arm/armv8-aes.c \ wolfcrypt/src/port/arm/armv8-sha256.c \ wolfcrypt/src/port/arm/armv8-chacha.c \ + wolfcrypt/src/port/aria/aria-crypt.c \ + wolfcrypt/src/port/aria/aria-cryptocb.c \ wolfcrypt/src/port/nxp/ksdk_port.c \ wolfcrypt/src/port/nxp/dcp_port.c \ wolfcrypt/src/port/nxp/se050_port.c \ diff --git a/wolfcrypt/src/port/aria/aria-crypt.c b/wolfcrypt/src/port/aria/aria-crypt.c new file mode 100644 index 000000000..7d77ea480 --- /dev/null +++ b/wolfcrypt/src/port/aria/aria-crypt.c @@ -0,0 +1,270 @@ +/* aria-crypt.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* + +DESCRIPTION +This library provides the interfaces to the ARIA cipher, an encryption algorithm +developed by the Korean Agency for Technology (KATS). It uses a 128-bit block +size and a key size of 128, 192, or 256 bits. + +*/ +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include + +#ifdef HAVE_ARIA + /* return 0 on success or WC_INIT_E on failure */ + int wc_AriaInitCrypt(wc_Aria* aria, MC_ALGID algo) + { + MC_RV rv = MC_OK; + + MC_APIMODE gApimode = MC_MODE_KCMV; + MC_ALGMODE algMode = MC_ALGMODE_GCM; + MC_PADTYPE algPad = MC_PADTYPE_NONE; + + if (aria == NULL) return BAD_FUNC_ARG; + + if (rv == MC_OK) rv = MC_Initialize(NULL); + + if (rv == MC_OK) rv = wc_AriaFreeCrypt(aria); + + if (rv == MC_OK) rv = MC_OpenSession(&(aria->hSession)); + + if (rv == MC_OK) rv = MC_SetApiMode(aria->hSession, gApimode); + + if (rv == MC_OK) rv = MC_SetOption(aria->hSession, algMode, algPad); + + if (rv == MC_OK) { + aria->algo = algo; + XMEMSET(aria->nonce,0,sizeof(aria->nonce)); + aria->nonceSz = 0; + } + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return WC_INIT_E; + } + return 0; + } + + /* return 0 on success or BAD_STATE_E on failure */ + int wc_AriaFreeCrypt(wc_Aria* aria) + { + if (aria == NULL) return 0; + + MC_RV rv = MC_OK; + if (aria->hKey != NULL) { + if (rv == MC_OK) rv = MC_DestroyObject(aria->hSession, aria->hKey); + if (rv == MC_OK) aria->hKey = NULL; + } + if (aria->hSession != NULL) { + if (rv == MC_OK) rv = MC_CloseSession(aria->hSession); + if (rv == MC_OK) aria->hSession = NULL; + } + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_STATE_E; + } + return 0; + } + + /* return 0 on success or BAD_FUNC_ARG/PUBLIC_KEY_E on failure */ + int wc_AriaSetKey(wc_Aria* aria, byte* key) + { + MC_RV rv = MC_OK; + MC_UINT keylen; + if (aria->algo == MC_ALGID_ARIA_128BITKEY) { + keylen = ARIA_128_KEY_SIZE; + } else if (aria->algo == MC_ALGID_ARIA_192BITKEY) { + keylen = ARIA_192_KEY_SIZE; + } else if (aria->algo == MC_ALGID_ARIA_256BITKEY) { + keylen = ARIA_256_KEY_SIZE; + } else { + WOLFSSL_MSG_EX("Unsupported algorithm: %d", aria->algo); + return PUBLIC_KEY_E; + } + + if (aria->hKey != NULL) { + if (rv == MC_OK) rv = MC_DestroyObject(aria->hSession, aria->hKey); + if (rv == MC_OK) aria->hKey = NULL; + } + if (rv == MC_OK) rv = MC_CreateObject(aria->hSession, (MC_UCHAR*)key, keylen, &(aria->hKey)); + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_FUNC_ARG; + } + return 0; + } + + static WARN_UNUSED_RESULT WC_INLINE int CheckAriaGcmIvSize(int ivSz) { + return (ivSz == GCM_NONCE_MIN_SZ || + ivSz == GCM_NONCE_MID_SZ || + ivSz == GCM_NONCE_MAX_SZ); + } + + /* return 0 on success or BAD_FUNC_ARG on failure */ + int wc_AriaGcmSetExtIV(wc_Aria* aria, const byte* iv, word32 ivSz) + { + int ret = 0; + + if (aria == NULL || iv == NULL || !CheckAriaGcmIvSize((int)ivSz)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + XMEMCPY((byte*)aria->nonce, iv, ivSz); + aria->nonceSz = ivSz; + } + + return ret; + } + + /* return 0 on success or BAD_FUNC_ARG on failure */ + int wc_AriaGcmSetIV(wc_Aria* aria, word32 ivSz, + const byte* ivFixed, word32 ivFixedSz, + WC_RNG* rng) + { + int ret = 0; + + if (aria == NULL || rng == NULL || !CheckAriaGcmIvSize((int)ivSz) || + (ivFixed == NULL && ivFixedSz != 0) || + (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + byte* iv = (byte*)aria->nonce; + + if (ivFixedSz) + XMEMCPY(iv, ivFixed, ivFixedSz); + + ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz); + } + + if (ret == 0) { + aria->nonceSz = ivSz; + } + + return ret; + } + + /* 'out' buffer is expected to be 'inSz + authTagSz' + * return 0 on success or BAD_FUNC_ARG/ENCRYPT_ERROR on failure */ + int wc_AriaEncrypt(wc_Aria* aria, byte* out, byte* in, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, + byte* authTag, word32 authTagSz) + { + MC_RV rv = MC_OK; + + MC_ALGPARAM param = { + .pNonce = iv, + .nNonce = ivSz, + .pAData = aad, + .nAData = aadSz, + .nTLen = authTagSz, + .nDataLen = inSz + }; + MC_ALGORITHM mcAlg = {aria->algo, NULL, 0}; + mcAlg.pParam = (MC_UCHAR*)¶m; + mcAlg.nParam = sizeof(param); + MC_UINT outSz = inSz + authTagSz; + + if (authTag == NULL || iv == NULL || authTagSz > ARIA_BLOCK_SIZE || + authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ || + ivSz == 0 || ivSz > ARIA_BLOCK_SIZE) { + return BAD_FUNC_ARG; + } + if (out == NULL || in == NULL || inSz == 0) { + return BAD_FUNC_ARG; + } + if (out <= in + inSz && in <= out + inSz) { /* check for overlapping range */ + return BAD_FUNC_ARG; + } + + if (rv == MC_OK) rv = MC_EncryptInit(aria->hSession, &mcAlg, aria->hKey); + + if (rv == MC_OK) rv = MC_Encrypt(aria->hSession, in, inSz, out, &outSz); + + if (rv == MC_OK) XMEMCPY(authTag, out + inSz, authTagSz); + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return ENCRYPT_ERROR; + } + return 0; + } + + /* 'in' buffer is expected to be 'inSz + authTagSz' + * return 0 on success or BAD_FUNC_ARG/ENCRYPT_ERROR on failure */ + int wc_AriaDecrypt(wc_Aria* aria, byte* out, byte* in, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, + byte* authTag, word32 authTagSz) + { + MC_RV rv = MC_OK; + + MC_ALGPARAM param = { + .pNonce = iv, + .nNonce = ivSz, + .pAData = aad, + .nAData = aadSz, + .nTLen = authTagSz, + .nDataLen = inSz + }; + MC_ALGORITHM mcAlg = {aria->algo, NULL, 0}; + mcAlg.pParam = (MC_UCHAR*)¶m; + mcAlg.nParam = sizeof(param); + MC_UINT outSz = inSz; + + if (authTag == NULL || iv == NULL || authTagSz > ARIA_BLOCK_SIZE || + authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ || + ivSz == 0 || ivSz > ARIA_BLOCK_SIZE) { + return BAD_FUNC_ARG; + } + if (out == NULL || in == NULL || inSz == 0) { + return BAD_FUNC_ARG; + } + if (out <= in + inSz && in <= out + inSz) { /* check for overlapping range */ + return BAD_FUNC_ARG; + } + + if (rv == MC_OK) rv = MC_DecryptInit(aria->hSession, &mcAlg, aria->hKey); + + if (rv == MC_OK) { + XMEMCPY((byte*)in + inSz, authTag, authTagSz); + inSz += authTagSz; + } + if (rv == MC_OK) rv = MC_Decrypt(aria->hSession, in, inSz, out, &outSz); + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return DECRYPT_ERROR; + } + return 0; + } +#endif /* HAVE_ARIA */ diff --git a/wolfcrypt/src/port/aria/aria-cryptocb.c b/wolfcrypt/src/port/aria/aria-cryptocb.c new file mode 100644 index 000000000..f62d4cdd0 --- /dev/null +++ b/wolfcrypt/src/port/aria/aria-cryptocb.c @@ -0,0 +1,550 @@ +/* aria.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* + +DESCRIPTION +This library provides the interfaces to the ARIA cipher, an encryption algorithm +developed by the Korean Agency for Technology (KATS). It uses a 128-bit block +size and a key size of 128, 192, or 256 bits. + +*/ +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include + + int wc_AriaInit(void) + { + MC_RV rv = MC_OK; + static char isInit = 0; + + if (isInit == 0) { + if (rv == MC_OK) rv = MC_Initialize(NULL); + if (rv == MC_OK) isInit = 1; + + #ifdef WOLF_CRYPTO_CB + if (rv == MC_OK) { + rv = wc_CryptoDev_RegisterDevice(WOLFSSL_ARIA_DEVID, wc_AriaCryptoCb, NULL); + } + #endif + } + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return WC_INIT_E; + } + return 0; + } + + /* return 0 on success or WC_INIT_E on failure */ + int wc_AriaInitSha(MC_HSESSION* hSession, MC_ALGID algo) + { + MC_RV rv = MC_OK; + + MC_APIMODE gApimode = MC_MODE_KCMV; + MC_ALGORITHM mcAlg = {algo, NULL, 0}; + + WOLFSSL_MSG_EX("AriaInitSha(0x%X)",algo); + + if (hSession == NULL) { + return BAD_FUNC_ARG; + } + + if (rv == MC_OK) rv = wc_AriaInit(); + + if (rv == MC_OK) rv = MC_OpenSession(hSession); + + if (rv == MC_OK) rv = MC_SetApiMode(*hSession, gApimode); + + if (rv == MC_OK) rv = MC_DigestInit(*hSession, &mcAlg); + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return WC_INIT_E; + } + return 0; + } + + /* return 0 on success or BAD_FUNC_ARG on failure */ + int wc_AriaShaUpdate(MC_HSESSION hSession, byte* data, word32 len) + { + MC_RV rv = MC_OK; + WOLFSSL_ENTER("AriaShaUpdate"); + + if (data == NULL) { + return BAD_FUNC_ARG; + } + + if (rv == MC_OK) rv = MC_DigestUpdate(hSession, data, len); + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_FUNC_ARG; + } + return 0; + } + + /* return 0 on success or BAD_FUNC_ARG on failure */ + int wc_AriaShaFinal(MC_HSESSION hSession, byte* out, word32* len) + { + MC_RV rv = MC_OK; + WOLFSSL_ENTER("AriaShaFinal"); + + if (out == NULL || len == NULL) { + return BAD_FUNC_ARG; + } + + /* Do an extra DigestUpdate noop just in case it is never explicitly called. */ + if (rv == MC_OK) rv = MC_DigestUpdate(hSession, NULL, 0); + + if (rv == MC_OK) rv = MC_DigestFinal(hSession, out, len); + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_FUNC_ARG; + } + /* WOLFSSL_MSG_EX("Digest len: %d", *len); */ + return 0; + } + + /* return 0 on success or BAD_STATE_E on failure */ + int wc_AriaFree(MC_HSESSION* hSession, MC_HOBJECT *obj1) + { + MC_RV rv = MC_OK; + WOLFSSL_ENTER("AriaFree"); + + if (hSession == NULL && obj1 != NULL) { + return BAD_FUNC_ARG; + } + + if (obj1 != NULL) { + if (rv == MC_OK) rv = MC_DestroyObject(*hSession, *obj1); + if (rv == MC_OK) *obj1 = NULL; + } + + if (hSession != NULL) { + if (rv == MC_OK) rv = MC_CloseSession(*hSession); + if (rv == MC_OK) *hSession = NULL; + } + + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_STATE_E; + } + return 0; + } + + int wc_AriaSign(byte* in, word32 inSz, byte* out, word32* outSz, ecc_key* key) + { + MC_HOBJECT hPrikey = 0; + MC_HSESSION hSession = 0; + + const ecc_set_type* dp; + MC_RV rv = MC_OK; + + MC_APIMODE gApimode = MC_MODE_KCMV; + MC_ALGORITHM mcAlg = {MC_ALGID_NONE, NULL, 0}; + byte keyAsn1[128]; + word32 keyAsn1Sz=(word32)sizeof(keyAsn1); + + WOLFSSL_ENTER("AriaSign"); + + if (in == NULL || out == NULL || outSz == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + if (rv == MC_OK) rv = wc_AriaInit(); + + if (rv == MC_OK) rv = MC_OpenSession(&hSession); + + if (rv == MC_OK) rv = MC_SetApiMode(hSession, gApimode); + + if (rv == MC_OK) { + int ret = wc_EccPrivateKeyToDerNoCurve(key,keyAsn1,keyAsn1Sz); + if (ret < 0) { rv = ret; } + else { keyAsn1Sz = ret; } + } + + WOLFSSL_MSG_EX("AriaSign key(%d):",keyAsn1Sz); + WOLFSSL_BUFFER(keyAsn1,keyAsn1Sz); + + WOLFSSL_MSG_EX("AriaSign rv=%d",rv); + + if (key->dp != NULL) { + dp = key->dp; + } + else { + dp = wc_ecc_get_curve_params(key->idx); + } + + if (dp->id == ECC_SECP256R1) { + mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P256_r1; + } else if (dp->id == ECC_SECP224R1) { + mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P224_12; + } else { + rv = MC_ERR_UNSUPPORTED_ALGORITHM; + } + + if (rv == MC_OK) rv = MC_CreateObject(hSession, keyAsn1, keyAsn1Sz, &hPrikey); + WOLFSSL_MSG_EX("AriaSign CreateObject rv=%d",rv); + + if (rv == MC_OK) rv = MC_SignInit(hSession, &mcAlg, hPrikey); + WOLFSSL_MSG_EX("AriaSign SignInit rv=%d",rv); + + if (rv == MC_OK) rv = MC_Sign(hSession, in, inSz, out, outSz); + WOLFSSL_MSG_EX("AriaSign Sign rv=%d",rv); + + wc_AriaFree(&hSession, &hPrikey); + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_STATE_E; + } + return 0; + } + + int wc_AriaVerify(byte* sig, word32 sigSz, byte* hash, word32 hashSz, int* res, ecc_key* key) + { + MC_HOBJECT hPubkey = 0; + MC_HSESSION hSession = 0; + + const ecc_set_type* dp; + MC_RV rv = MC_OK; + + MC_APIMODE gApimode = MC_MODE_KCMV; + MC_ALGORITHM mcAlg = {MC_ALGID_NONE, NULL, 0}; + byte keyarr[128]; + word32 keySz=sizeof(keyarr); + + WOLFSSL_ENTER("AriaVerify"); + + if (sig == NULL || hash == NULL || res == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + *res = 0; /* Default to invalid signature */ + + if (rv == MC_OK) rv = wc_AriaInit(); + + if (rv == MC_OK) rv = MC_OpenSession(&hSession); + + if (rv == MC_OK) rv = MC_SetApiMode(hSession, gApimode); + + if (rv == MC_OK) { + int ret = wc_EccPublicKeyToDer(key,keyarr,keySz,0); + if (ret < 0) { rv = ret; } + else { keySz = ret; } + } + + WOLFSSL_MSG_EX("AriaVerify key(%d):",keySz); + WOLFSSL_BUFFER(keyarr,keySz); + + WOLFSSL_MSG_EX("AriaVerify rv=%d",rv); + + if (key->dp != NULL) { + dp = key->dp; + } + else { + dp = wc_ecc_get_curve_params(key->idx); + } + + if (dp->id == ECC_SECP256R1) { + mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P256_r1; + } else if (dp->id == ECC_SECP224R1) { + mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P224_12; + } else { + rv = MC_ERR_UNSUPPORTED_ALGORITHM; + } + + if (rv == MC_OK) rv = MC_CreateObject(hSession, keyarr, keySz, &hPubkey); + WOLFSSL_MSG_EX("AriaVerify CreateObject rv=%d",rv); + + if (rv == MC_OK) rv = MC_VerifyInit(hSession, &mcAlg, hPubkey); + WOLFSSL_MSG_EX("AriaVerify VerifyInit rv=%d",rv); + + if (rv == MC_OK) rv = MC_Verify(hSession, hash, hashSz, sig, sigSz); + WOLFSSL_MSG_EX("AriaVerify Verify rv=%d",rv); + + wc_AriaFree(&hSession, &hPubkey); + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_STATE_E; + } + *res = 1; /* Valid signature */ + return 0; + } + + int wc_AriaDerive(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outSz) + { + MC_HOBJECT hPrikey = 0; + MC_HSESSION hSession = 0; + + const ecc_set_type* dp; + MC_RV rv = MC_OK; + + MC_APIMODE gApimode = MC_MODE_KCMV; + MC_ALGORITHM mcAlg = {MC_ALGID_NONE, NULL, 0}; + byte pubAsn1[128]; + word32 pubAsn1Sz=sizeof(pubAsn1); + byte privAsn1[128]; + word32 privAsn1Sz=sizeof(privAsn1); + + WOLFSSL_ENTER("AriaDerive"); + + if (private_key == NULL || public_key == NULL || out == NULL || outSz == NULL) { + return BAD_FUNC_ARG; + } + + if (rv == MC_OK) rv = wc_AriaInit(); + + if (rv == MC_OK) rv = MC_OpenSession(&hSession); + + if (rv == MC_OK) rv = MC_SetApiMode(hSession, gApimode); + + if (rv == MC_OK) { + int ret = wc_EccPublicKeyToDer(public_key,pubAsn1,pubAsn1Sz,0); + if (ret < 0) { rv = ret; } + else { pubAsn1Sz = ret; } + WOLFSSL_MSG_EX("AriaDerive PublicKeyToDer ret=%d",ret); + } + WOLFSSL_MSG_EX("AriaVerify pubAsn1(%d):",pubAsn1Sz); + WOLFSSL_BUFFER(pubAsn1,pubAsn1Sz); + mcAlg.pParam=pubAsn1; + mcAlg.nParam=pubAsn1Sz; + + if (rv == MC_OK) { + int ret = wc_EccPrivateKeyToDerNoCurve(private_key,privAsn1,privAsn1Sz); + if (ret < 0) { rv = ret; } + else { privAsn1Sz = ret; } + WOLFSSL_MSG_EX("AriaDerive PrivateKeyToDer ret=%d",ret); + } + WOLFSSL_MSG_EX("AriaVerify privAsn1(%d):",privAsn1Sz); + WOLFSSL_BUFFER(privAsn1,privAsn1Sz); + + if (private_key->dp != NULL) { + dp = private_key->dp; + } + else { + dp = wc_ecc_get_curve_params(private_key->idx); + } + + if (dp->id == ECC_SECP256R1) { + mcAlg.mcAlgId = MC_ALGID_ECDH_P256_r1; + } else if (dp->id == ECC_SECP224R1) { + mcAlg.mcAlgId = MC_ALGID_ECDH_P224_12; + } else { + rv = MC_ERR_UNSUPPORTED_ALGORITHM; + } + + if (rv == MC_OK) rv = MC_CreateObject(hSession, privAsn1, privAsn1Sz, &hPrikey); + WOLFSSL_MSG_EX("AriaDerive CreateObject rv=%d",rv); + + if (rv == MC_OK) rv = MC_DeriveKey(hSession, &mcAlg, hPrikey, out, outSz); + WOLFSSL_MSG_EX("AriaDerive DeriveKey rv=%d",rv); + + wc_AriaFree(&hSession, &hPrikey); + if (rv != MC_OK) { + WOLFSSL_MSG(MC_GetErrorString(rv)); + return BAD_STATE_E; + } + return 0; + } + +#ifdef WOLF_CRYPTO_CB +static void printOutput(const char* strName, unsigned char* data, unsigned int dataSz) +{ + #ifdef DEBUG_WOLFSSL + WOLFSSL_MSG_EX("%s (%d):", strName,dataSz); + WOLFSSL_BUFFER(data,dataSz); + #else + #if 0 + unsigned int i; + int line = 1; + + printf("%s:\n",strName); + printf(" "); + for(i=1; i<=dataSz; i++) + { + printf(",0x%02X", data[i-1]); + if(!(i%16) && i!= dataSz) printf("\n "); + else if(!(i%4)) printf(" "); + } + printf("\n"); + #else + (void)strName; + (void)data; + (void)dataSz; + #endif + #endif +} + +int wc_AriaCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */ + (void)ctx; + + if (info == NULL) + return BAD_FUNC_ARG; + +#ifdef DEBUG_CRYPTOCB + wc_CryptoCb_InfoString(info); +#endif + + if (info->algo_type == WC_ALGO_TYPE_PK) { + if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + /* set devId to invalid, so software is used */ + info->pk.eccsign.key->devId = INVALID_DEVID; + + printOutput((char *)"eccsign.in (before)", + (byte *)info->pk.eccsign.in,info->pk.eccsign.inlen); + printOutput((char *)"eccsign.out(before)", + (byte *)info->pk.eccsign.out,*(info->pk.eccsign.outlen)); + printOutput((char *)"eccsign.key(before)", + (byte *)info->pk.eccsign.key,sizeof(info->pk.eccsign.key)); + + byte buf[128]; + word32 bufSz = sizeof(buf); + ret = wc_AriaSign((byte *)info->pk.eccsign.in,info->pk.eccsign.inlen, + buf,&bufSz, + info->pk.eccsign.key); + if (ret != 0) { + ret = CRYPTOCB_UNAVAILABLE; + } else { + memcpy(info->pk.eccsign.out, buf, bufSz); + *(info->pk.eccsign.outlen) = bufSz; + } + + printOutput((char *)"eccsign.in (after)", + (byte *)info->pk.eccsign.in,info->pk.eccsign.inlen); + printOutput((char *)"eccsign.out(after)", + (byte *)info->pk.eccsign.out,*(info->pk.eccsign.outlen)); + printOutput((char *)"eccsign.key(after)", + (byte *)info->pk.eccsign.key,sizeof(info->pk.eccsign.key)); + + /* reset devId */ + info->pk.eccsign.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + /* set devId to invalid, so software is used */ + info->pk.eccverify.key->devId = INVALID_DEVID; + + printOutput((char *)"eccverify.sig (before)", + (byte *)info->pk.eccverify.sig,info->pk.eccverify.siglen); + printOutput((char *)"eccverify.hash(before)", + (byte *)info->pk.eccverify.hash,info->pk.eccverify.hashlen); + printOutput((char *)"eccverify.key (before)", + (byte *)info->pk.eccverify.key,sizeof(info->pk.eccverify.key)); + + ret = wc_AriaVerify((byte *)info->pk.eccverify.sig,info->pk.eccverify.siglen, + (byte *)info->pk.eccverify.hash, info->pk.eccverify.hashlen, + info->pk.eccverify.res, info->pk.eccverify.key); + + printOutput((char *)"eccverify.sig (after)", + (byte *)info->pk.eccverify.sig,info->pk.eccverify.siglen); + printOutput((char *)"eccverify.hash(after)", + (byte *)info->pk.eccverify.hash,info->pk.eccverify.hashlen); + printOutput((char *)"eccverify.key (after)", + (byte *)info->pk.eccverify.key,sizeof(info->pk.eccverify.key)); + + if (ret != 0) ret = CRYPTOCB_UNAVAILABLE; + /* reset devId */ + info->pk.eccverify.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDH) { + /* set devId to invalid, so software is used */ + info->pk.ecdh.private_key->devId = INVALID_DEVID; + + ret = wc_AriaDerive( + info->pk.ecdh.private_key, info->pk.ecdh.public_key, + info->pk.ecdh.out, info->pk.ecdh.outlen); + + if (ret != 0) ret = CRYPTOCB_UNAVAILABLE; + /* reset devId */ + info->pk.ecdh.private_key->devId = devIdArg; + } + } + else if (info->algo_type == WC_ALGO_TYPE_HASH) { + if (info->hash.type == WC_HASH_TYPE_SHA256) { + if (info->hash.sha256 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha256->devId = INVALID_DEVID; + + if (info->hash.sha256->hSession == NULL) { + ret = wc_AriaInitSha(&(info->hash.sha256->hSession), MC_ALGID_SHA256); + } + + if (((ret == 0) || (ret == CRYPTOCB_UNAVAILABLE)) + && (info->hash.in != NULL)) { + ret = wc_AriaShaUpdate(info->hash.sha256->hSession, + (byte *) info->hash.in, info->hash.inSz); + } + if (((ret == 0) || (ret == CRYPTOCB_UNAVAILABLE)) + && (info->hash.digest != NULL)) { + MC_UINT digestSz = 32; + ret = wc_AriaShaFinal(info->hash.sha256->hSession, + info->hash.digest, &digestSz); + if ((ret == 0) || (ret == CRYPTOCB_UNAVAILABLE)) + ret = wc_AriaFree(&(info->hash.sha256->hSession),NULL); + } + if (ret != 0) ret = CRYPTOCB_UNAVAILABLE; + /* reset devId */ + info->hash.sha256->devId = devIdArg; + } + else if (info->hash.type == WC_HASH_TYPE_SHA384) { + if (info->hash.sha384 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha384->devId = INVALID_DEVID; + + if (info->hash.sha384->hSession == NULL) { + ret = wc_AriaInitSha(&(info->hash.sha384->hSession), MC_ALGID_SHA384); + } + + if (((ret == 0) || (ret == CRYPTOCB_UNAVAILABLE)) + && (info->hash.in != NULL)) { + ret = wc_AriaShaUpdate(info->hash.sha384->hSession, + (byte *) info->hash.in, info->hash.inSz); + } + if (((ret == 0) || (ret == CRYPTOCB_UNAVAILABLE)) + && (info->hash.digest != NULL)) { + MC_UINT digestSz = 48; + ret = wc_AriaShaFinal(info->hash.sha384->hSession, + info->hash.digest, &digestSz); + if ((ret == 0) || (ret == CRYPTOCB_UNAVAILABLE)) + ret = wc_AriaFree(&(info->hash.sha384->hSession),NULL); + } + if (ret != 0) ret = CRYPTOCB_UNAVAILABLE; + /* reset devId */ + info->hash.sha384->devId = devIdArg; + } + } + + return ret; +} +#endif /* WOLF_CRYPTO_CB */ diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index ffdd4019a..c026c34c2 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -266,6 +266,10 @@ static int InitSha256(wc_Sha256* sha256) XMEMSET(&sha256->maxq_ctx, 0, sizeof(sha256->maxq_ctx)); #endif +#ifdef HAVE_ARIA + sha256->hSession = NULL; +#endif + return ret; } #endif @@ -1831,6 +1835,13 @@ void wc_Sha256Free(wc_Sha256* sha256) wc_MAXQ10XX_Sha256Free(sha256); #endif +#ifdef HAVE_ARIA + if (sha256->hSession != NULL) { + MC_CloseSession(sha256->hSession); + sha256->hSession = NULL; + } +#endif + /* Espressif embedded hardware acceleration specific: */ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) if (sha256->ctx.lockDepth > 0) { @@ -2085,6 +2096,13 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) esp_sha256_ctx_copy(src, dst); #endif +#ifdef HAVE_ARIA + dst->hSession = NULL; + if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) { + return MEMORY_E; + } +#endif + #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 3d17a09b4..c800da0ea 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -1364,6 +1364,10 @@ static int InitSha384(wc_Sha384* sha384) sha384->flags = 0; #endif +#ifdef HAVE_ARIA + sha384->hSession = NULL; +#endif + #ifdef WOLFSSL_HASH_KEEP sha384->msg = NULL; sha384->len = 0; @@ -1549,6 +1553,13 @@ void wc_Sha384Free(wc_Sha384* sha384) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384) wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384); #endif /* WOLFSSL_ASYNC_CRYPT */ + +#ifdef HAVE_ARIA + if (sha384->hSession != NULL) { + MC_CloseSession(sha384->hSession); + sha384->hSession = NULL; + } +#endif } #endif /* WOLFSSL_SHA384 */ @@ -1880,6 +1891,13 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) esp_sha384_ctx_copy(src, dst); #endif +#ifdef HAVE_ARIA + dst->hSession = NULL; + if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) { + return MEMORY_E; + } +#endif + #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a8c14b166..401e06c2b 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -85,6 +85,9 @@ #if defined(WOLFSSL_CAAM) #include #endif +#if defined(HAVE_ARIA) + #include +#endif #if defined(WOLFSSL_DEVCRYPTO) #include #endif @@ -367,6 +370,12 @@ int wolfCrypt_Init(void) } #endif +#if defined(HAVE_ARIA) + if ((ret = wc_AriaInit()) != 0) { + return ret; + } +#endif + #ifdef WOLFSSL_IMXRT_DCP if ((ret = wc_dcp_init()) != 0) { return ret; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 674f8f375..728935c8e 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -628,6 +628,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t memcb_test(void); #ifdef WOLFSSL_CAAM_BLOB WOLFSSL_TEST_SUBROUTINE wc_test_ret_t blob_test(void); #endif +#ifdef HAVE_ARIA +#include "wolfssl/wolfcrypt/port/aria/aria-crypt.h" +void printOutput(const char *strName, unsigned char *data, unsigned int dataSz); +WOLFSSL_TEST_SUBROUTINE int ariagcm_test(MC_ALGID); +#endif #ifdef WOLF_CRYPTO_CB WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void); @@ -1387,6 +1392,23 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #endif +#ifdef HAVE_ARIA + if ( (ret = ariagcm_test(MC_ALGID_ARIA_128BITKEY)) != 0) + TEST_FAIL("ARIA128 test failed!\n", ret); + else + TEST_PASS("ARIA128 test passed!\n"); + + if ( (ret = ariagcm_test(MC_ALGID_ARIA_192BITKEY)) != 0) + TEST_FAIL("ARIA192 test failed!\n", ret); + else + TEST_PASS("ARIA192 test passed!\n"); + + if ( (ret = ariagcm_test(MC_ALGID_ARIA_256BITKEY)) != 0) + TEST_FAIL("ARIA256 test failed!\n", ret); + else + TEST_PASS("ARIA256 test passed!\n"); +#endif + #ifdef HAVE_CAMELLIA if ( (ret = camellia_test()) != 0) TEST_FAIL("CAMELLIA test failed!\n", ret); @@ -13007,6 +13029,86 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aeskeywrap_test(void) #endif /* NO_AES */ +#ifdef HAVE_ARIA +void printOutput(const char *strName, unsigned char *data, unsigned int dataSz) +{ + #ifndef DEBUG_WOLFSSL + (void)strName; + (void)data; + (void)dataSz; + #else + WOLFSSL_MSG_EX("%s (%d):", strName,dataSz); + WOLFSSL_BUFFER(data,dataSz); + #endif +} + +WOLFSSL_TEST_SUBROUTINE int ariagcm_test(MC_ALGID algo) +{ + int ret = 0; + byte data[] = TEST_STRING; + word32 dataSz = TEST_STRING_SZ; + + /* Arbitrarily random long key that we will truncate to the right size */ + byte key[] = { 0x1E, 0xCC, 0x95, 0xCB, 0xD3, 0x74, 0x58, 0x4F, + 0x6F, 0x8A, 0x70, 0x26, 0xF7, 0x3C, 0x8D, 0xB6, + 0xDC, 0x32, 0x76, 0x20, 0xCF, 0x05, 0x4A, 0xCF, + 0x11, 0x86, 0xCD, 0x23, 0x5E, 0xC1, 0x6E, 0x2B }; + byte cipher[2*TEST_STRING_SZ], plain[TEST_STRING_SZ], ad[256], authTag[AES_BLOCK_SIZE]; + word32 keySz, adSz = 256, authTagSz = sizeof(authTag); + + wc_Aria aria; + XMEMSET((void *)&aria, 0, sizeof(aria)); + ret = wc_AriaInitCrypt(&aria, algo); + if (ret != 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(ret),out); } + + ret = wc_AriaSetKey(&aria, key); + if (ret != 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(ret),out); } + + MC_GetObjectValue(aria.hSession, aria.hKey, key, &keySz); + printOutput("Key", key, keySz); + + WC_RNG rng; + + ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + ret = wc_AriaGcmSetIV(&aria, GCM_NONCE_MID_SZ, NULL, 0, &rng); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + wc_FreeRng(&rng); + + printOutput("Plaintext", data, sizeof(data)); + XMEMSET(cipher, 0, sizeof(cipher)); + + ret = wc_AriaEncrypt(&aria, cipher, data, dataSz, + (byte *)aria.nonce, aria.nonceSz, ad, adSz, + authTag, authTagSz); + if (ret != 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(ret),out); } + + printOutput("Ciphertext", cipher, sizeof(cipher)); + printOutput("AuthTag", authTag, sizeof(authTag)); + + XMEMSET(plain, 0, sizeof(plain)); + + ret = wc_AriaDecrypt(&aria, plain, cipher, dataSz, + (byte *)aria.nonce, aria.nonceSz, ad, adSz, + authTag, authTagSz); + if (ret != 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(ret),out); } + + printOutput("Plaintext", plain, sizeof(plain)); + + if (XMEMCMP(plain, data, dataSz) != 0) + ERROR_OUT(WC_TEST_RET_ENC_NC,out); +out: + if (ret != 0) { wc_AriaFreeCrypt(&aria); } + else { ret = wc_AriaFreeCrypt(&aria); } + + return ret; +} +#endif /* HAVE_ARIA */ + #ifdef HAVE_CAMELLIA diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 186c9e036..c4c8ead45 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -55,6 +55,9 @@ #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && defined(OPENSSL_EXTRA) #include #endif +#ifdef HAVE_ARIA + #include +#endif #ifdef HAVE_CAMELLIA #include #endif @@ -649,6 +652,10 @@ #endif #endif #endif /* NO_AES */ + #ifdef HAVE_ARIA + #define BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 + #define BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 + #endif /* HAVE_ARIA */ #if !defined(NO_RC4) && !defined(WSSL_HARDEN_TLS) /* MUST NOT negotiate RC4 cipher suites * https://www.rfc-editor.org/rfc/rfc9325#section-4.1 */ @@ -954,6 +961,11 @@ #define NO_AESGCM_AEAD #endif +#if defined(BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256) || \ + defined(BUILD_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384) + #define BUILD_ARIA +#endif + #if defined(BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256) || \ defined(BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256) || \ defined(BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256) || \ @@ -999,6 +1011,7 @@ #if defined(WOLFSSL_MAX_STRENGTH) || \ (defined(HAVE_AESGCM) && !defined(NO_AESGCM_AEAD)) || \ defined(HAVE_AESCCM) || \ + defined(HAVE_ARIA) || \ (defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \ !defined(NO_CHAPOL_AEAD)) || \ defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) || \ @@ -1171,6 +1184,12 @@ enum { TLS_SHA256_SHA256 = 0xB4, TLS_SHA384_SHA384 = 0xB5, + /* ARIA-GCM, first byte is 0xC0 (ECC_BYTE) + * See: https://www.rfc-editor.org/rfc/rfc6209.html#section-5 + */ + TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0x5c, + TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0x5d, + /* TLS v1.3 SM cipher suites - 0x00 (CIPHER_BYTE) is first byte */ TLS_SM4_GCM_SM3 = 0xC6, TLS_SM4_CCM_SM3 = 0xC7, @@ -3986,8 +4005,8 @@ enum CipherType { aead }; #endif -#if defined(BUILD_AES) || defined(BUILD_AESGCM) || (defined(HAVE_CHACHA) && \ - defined(HAVE_POLY1305)) || defined(WOLFSSL_TLS13) +#if defined(BUILD_AES) || defined(BUILD_AESGCM) || defined(HAVE_ARIA) || \ + (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(WOLFSSL_TLS13) #define CIPHER_NONCE #endif @@ -4016,10 +4035,12 @@ typedef struct Ciphers { #endif #if defined(BUILD_AES) || defined(BUILD_AESGCM) Aes* aes; - #if (defined(BUILD_AESGCM) || defined(HAVE_AESCCM)) && \ - !defined(WOLFSSL_NO_TLS12) - byte* additional; - #endif +#endif +#if (defined(BUILD_AESGCM) || defined(HAVE_AESCCM)) && !defined(WOLFSSL_NO_TLS12) + byte* additional; +#endif +#ifdef HAVE_ARIA + wc_Aria* aria; #endif #ifdef CIPHER_NONCE byte* nonce; diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 567c4a409..2481709d7 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -68,6 +68,10 @@ #include #endif +#ifdef HAVE_ARIA + #include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -142,6 +146,11 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ccm(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void); +#if defined(HAVE_ARIA) +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aria_128_gcm(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aria_192_gcm(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aria_256_gcm(void); +#endif WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void); @@ -236,6 +245,9 @@ typedef union { XtsAes xts; #endif #endif +#ifdef HAVE_ARIA + wc_Aria aria; +#endif #ifndef NO_DES3 Des des; Des3 des3; @@ -381,6 +393,9 @@ typedef union { #define NID_auth_null 1054 #define NID_auth_any 1055 /* Curve */ +#define NID_aria_128_gcm 1123 +#define NID_aria_192_gcm 1124 +#define NID_aria_256_gcm 1125 #define NID_sm2 1172 #define NID_X9_62_id_ecPublicKey EVP_PKEY_EC @@ -446,7 +461,10 @@ enum { SM4_CBC_TYPE = 44, SM4_CTR_TYPE = 45, SM4_GCM_TYPE = 46, - SM4_CCM_TYPE = 47 + SM4_CCM_TYPE = 47, + ARIA_128_GCM_TYPE = 48, + ARIA_192_GCM_TYPE = 49, + ARIA_256_GCM_TYPE = 50 }; #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -490,10 +508,10 @@ struct WOLFSSL_EVP_CIPHER_CTX { #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) byte* key; /* used in partial Init()s */ #endif -#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) || \ defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) || \ (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) -#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_ARIA) ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; #elif defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) ALIGN16 unsigned char authTag[SM4_BLOCK_SIZE]; @@ -973,6 +991,9 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_rc4 wolfSSL_EVP_rc4 #define EVP_chacha20 wolfSSL_EVP_chacha20 #define EVP_chacha20_poly1305 wolfSSL_EVP_chacha20_poly1305 +#define EVP_aria_128_gcm wolfSSL_EVP_aria_128_gcm +#define EVP_aria_192_gcm wolfSSL_EVP_aria_192_gcm +#define EVP_aria_256_gcm wolfSSL_EVP_aria_256_gcm #define EVP_sm4_ecb wolfSSL_EVP_sm4_ecb #define EVP_sm4_cbc wolfSSL_EVP_sm4_cbc #define EVP_sm4_ctr wolfSSL_EVP_sm4_ctr diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 63bbfb107..a38e91dfe 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3230,7 +3230,8 @@ enum BulkCipherAlgorithm { wolfssl_camellia = 10, wolfssl_sm4_cbc = 11, wolfssl_sm4_gcm = 12, - wolfssl_sm4_ccm = 13 + wolfssl_sm4_ccm = 13, + wolfssl_aria_gcm = 14 }; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 49b7ec03f..f63f74c24 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -750,6 +750,8 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); WOLFSSL_API int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen); WOLFSSL_API int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen); + WOLFSSL_API int wc_EccPrivateKeyToDerNoCurve(ecc_key* key, byte* output, + word32 inLen); WOLFSSL_API int wc_EccKeyDerSize(ecc_key* key, int pub); WOLFSSL_API int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen); diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index f8f4a81bb..452eabb49 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -81,6 +81,8 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/sm4.h noinst_HEADERS+= \ + wolfssl/wolfcrypt/port/aria/aria-crypt.h \ + wolfssl/wolfcrypt/port/aria/aria-cryptocb.h \ wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ wolfssl/wolfcrypt/port/ti/ti-hash.h \ wolfssl/wolfcrypt/port/ti/ti-ccm.h \ @@ -130,6 +132,11 @@ if BUILD_DEVCRYPTO nobase_include_HEADERS+= wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h endif +if BUILD_ARIA +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/aria/aria-crypt.h +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/aria/aria-cryptocb.h +endif + if BUILD_ASYNCCRYPT nobase_include_HEADERS+= wolfssl/wolfcrypt/async.h endif diff --git a/wolfssl/wolfcrypt/port/aria/aria-crypt.h b/wolfssl/wolfcrypt/port/aria/aria-crypt.h new file mode 100644 index 000000000..9d49b875a --- /dev/null +++ b/wolfssl/wolfcrypt/port/aria/aria-crypt.h @@ -0,0 +1,80 @@ +/* aria-crypt.h + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/port/aria/aria-crypt.h +*/ +/* + +DESCRIPTION +This library provides the interfaces to the ARIA cipher implementation for +encrypting and decrypting data. + +*/ +#ifndef WOLF_CRYPT_ARIA_CRYPT_H +#define WOLF_CRYPT_ARIA_CRYPT_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "mcapi.h" +#include "mcapi_error.h" + +#define ARIA_128_KEY_SIZE 16 +#define ARIA_192_KEY_SIZE 24 +#define ARIA_256_KEY_SIZE 32 + +#define ARIA_BLOCK_SIZE 16 +#define ARIA_GCM_AUTH_SZ 16 + +#define WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(x) (x+ARIA_GCM_AUTH_SZ) + +typedef struct { + MC_HSESSION hSession; + MC_ALGID algo; + MC_HOBJECT hKey; + word32 nonce[ARIA_BLOCK_SIZE / sizeof(word32)]; + word32 nonceSz; +} wc_Aria; + +WOLFSSL_API int wc_AriaInitCrypt(wc_Aria* aria, MC_ALGID algo); +WOLFSSL_API int wc_AriaFreeCrypt(wc_Aria* aria); +WOLFSSL_API int wc_AriaSetKey(wc_Aria* aria, byte* key); +WOLFSSL_API int wc_AriaGcmSetExtIV(wc_Aria* aria, const byte* iv, word32 ivSz); +WOLFSSL_API int wc_AriaGcmSetIV(wc_Aria* aria, word32 ivSz, + const byte* ivFixed, word32 ivFixedSz, + WC_RNG* rng); + +WOLFSSL_API int wc_AriaEncrypt(wc_Aria *aria, byte* out, byte* in, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, + byte* authTag, word32 authTagSz); +WOLFSSL_API int wc_AriaDecrypt(wc_Aria *aria, byte* out, byte* in, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, + byte* authTag, word32 authTagSz); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_ARIA_CRYPT_H */ diff --git a/wolfssl/wolfcrypt/port/aria/aria-cryptocb.h b/wolfssl/wolfcrypt/port/aria/aria-cryptocb.h new file mode 100644 index 000000000..d19281c2c --- /dev/null +++ b/wolfssl/wolfcrypt/port/aria/aria-cryptocb.h @@ -0,0 +1,64 @@ +/* aria-cryptocb.h + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/port/aria/aria-cryptocb.h +*/ +/* + +DESCRIPTION +This library provides the interfaces to the ARIA cipher implementation for +signing, verifying and hashing data. + +*/ +#ifndef WOLF_CRYPT_ARIA_CRYPTOCB_H +#define WOLF_CRYPT_ARIA_CRYPTOCB_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "mcapi.h" +#include "mcapi_error.h" + +int wc_AriaInit(void); +int wc_AriaInitSha(MC_HSESSION* hSession, MC_ALGID algo); +int wc_AriaShaUpdate(MC_HSESSION hSession, byte* data, word32 len); +int wc_AriaShaFinal(MC_HSESSION hSession, byte* out, word32* len); +int wc_AriaFree(MC_HSESSION* hSession, MC_HOBJECT *obj1); + +int wc_AriaSign(byte* in, word32 inSz, byte* out, word32* outSz, ecc_key* key); +int wc_AriaVerify(byte* sig, word32 sigSz, byte* hash, word32 hashSz, int* res, ecc_key* key); +int wc_AriaDerive(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outSz); +#ifdef WOLF_CRYPTO_CB + +#define WOLFSSL_ARIA_DEVID 8 +int wc_AriaCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_ARIA_CRYPTOCB_H */ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 51a91a052..77e1de5d2 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -169,6 +169,11 @@ enum { #include #endif +#ifdef HAVE_ARIA + #include "mcapi.h" + #include "mcapi_error.h" +#endif + /* wc_Sha256 digest */ struct wc_Sha256 { #ifdef FREESCALE_LTC_SHA @@ -235,6 +240,9 @@ struct wc_Sha256 { caam_hash_ctx_t ctx; caam_handle_t hndl; #endif +#ifdef HAVE_ARIA + MC_HSESSION hSession; +#endif #ifdef WOLFSSL_HASH_FLAGS word32 flags; /* enum wc_HashFlags in hash.h */ #endif @@ -329,4 +337,3 @@ WOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst); #endif /* NO_SHA256 */ #endif /* WOLF_CRYPT_SHA256_H */ - diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 07411b01d..f01ea0396 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -150,6 +150,10 @@ enum { #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" #endif +#ifdef HAVE_ARIA + #include "mcapi.h" + #include "mcapi_error.h" +#endif /* wc_Sha512 digest */ struct wc_Sha512 { #ifdef WOLFSSL_PSOC6_CRYPTO @@ -201,6 +205,9 @@ struct wc_Sha512 { caam_hash_ctx_t ctx; caam_handle_t hndl; #endif +#ifdef HAVE_ARIA + MC_HSESSION hSession; +#endif #endif /* WOLFSSL_PSOC6_CRYPTO */ }; @@ -342,4 +349,3 @@ WOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst); #endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */ #endif /* WOLF_CRYPT_SHA512_H */ -