diff --git a/ChangeLog b/ChangeLog index f71f8423..4446a1c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -476,7 +476,7 @@ fwknop-2.5 (07/19/2013): far more powerful. fwknop-2.0.4 (12/09/2012): - - [client] Misc fixes and the addition of save_args and last command + - [client] Misc fixes and the addition of save_args and last command (.fwknop.last) support on the Windows platform. - [client] Fixed bug in username determination code where a valid value could be overrwritten in certain circumstances. diff --git a/INSTALL b/INSTALL index 5458714e..6cc96d69 100644 --- a/INSTALL +++ b/INSTALL @@ -231,4 +231,3 @@ an Autoconf bug. Until the bug is fixed you can use this workaround: `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. - diff --git a/client/Makefile.am b/client/Makefile.am index 8e2f6aa2..41f38dc0 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -38,4 +38,3 @@ fwknop.8: $(top_srcdir)/client/fwknop.8.in clean-local: rm -f fwknop.8 fwknop_utests *.gcno *.gcda - diff --git a/client/config_init.c b/client/config_init.c index 82ed0b85..37f8503e 100644 --- a/client/config_init.c +++ b/client/config_init.c @@ -584,12 +584,12 @@ is_rc_param(const char *line, rc_file_param_t *param) } /** - * @brief Dump available stanzas from a fwknoprc file + * \brief Dump available stanzas from a fwknoprc file * * This function parses a rcfile and looks for configured stanzas. * They are all displayed except the default stanza. - * - * @param rcfile full path to the rcfile to parse + * + * \param rcfile full path to the rcfile to parse */ static int dump_configured_stanzas_from_rcfile(const char* rcfile) @@ -2638,7 +2638,7 @@ DECLARE_UTEST(check_var_bitmask, "Check var_bitmask functions") CU_ASSERT(var_bitmask.dw[0] == 1); remove_var_from_bitmask(FWKNOP_CLI_FIRST_ARG, &var_bitmask); CU_ASSERT(bitmask_has_var(FWKNOP_CLI_FIRST_ARG, &var_bitmask) == 0); - CU_ASSERT(var_bitmask.dw[0] == 0); + CU_ASSERT(var_bitmask.dw[0] == 0); add_var_to_bitmask(FWKNOP_CLI_ARG_KEY_RIJNDAEL, &var_bitmask); CU_ASSERT(bitmask_has_var(FWKNOP_CLI_ARG_KEY_RIJNDAEL, &var_bitmask) == 1); @@ -2654,7 +2654,7 @@ DECLARE_UTEST(check_var_bitmask, "Check var_bitmask functions") CU_ASSERT(bitmask_has_var(FWKNOP_CLI_LAST_ARG+32, &var_bitmask) == 0); add_var_to_bitmask(FWKNOP_CLI_LAST_ARG+34, &var_bitmask); - CU_ASSERT(bitmask_has_var(FWKNOP_CLI_LAST_ARG+34, &var_bitmask) == 0); + CU_ASSERT(bitmask_has_var(FWKNOP_CLI_LAST_ARG+34, &var_bitmask) == 0); } int register_ts_config_init(void) @@ -2667,4 +2667,3 @@ int register_ts_config_init(void) } #endif /* HAVE_C_UNIT_TESTS */ - diff --git a/client/fwknop.c b/client/fwknop.c index 16a972b2..5fc28351 100644 --- a/client/fwknop.c +++ b/client/fwknop.c @@ -839,7 +839,6 @@ set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const acc char nat_access_buf[MAX_LINE_LEN] = {0}; char tmp_access_port[MAX_PORT_STR_LEN+1] = {0}, *ndx = NULL; int access_port = 0, i = 0, is_err = 0; - char dst_ip_str[INET_ADDRSTRLEN] = {0}; char hostname[HOSTNAME_BUFSIZE] = {0}; int port = 0; struct addrinfo hints; diff --git a/client/log_msg.c b/client/log_msg.c index df110314..e83b7b15 100644 --- a/client/log_msg.c +++ b/client/log_msg.c @@ -65,8 +65,8 @@ log_free(void) /** * Set the verbosity level for the current context of the log module. - * - * @param level verbosity level to set + * + * \param level verbosity level to set */ void log_set_verbosity(int level) @@ -80,9 +80,9 @@ log_set_verbosity(int level) * This function sends a message to the stream dedicated to the priority * set. If the verbosity for the context is higher than the one used for * the message, then the message is discarded. - * - * @param level Verbosity level to used for the message. - * @param msg Message to print + * + * \param level Verbosity level to used for the message. + * \param msg Message to print */ void log_msg(int level, char* msg, ...) @@ -92,7 +92,7 @@ log_msg(int level, char* msg, ...) if (level <= log_ctx.verbosity) { va_start(ap, msg); - + switch (level) { case LOG_VERBOSITY_ERROR: @@ -103,7 +103,7 @@ log_msg(int level, char* msg, ...) case LOG_VERBOSITY_NORMAL: case LOG_VERBOSITY_INFO: case LOG_VERBOSITY_DEBUG: - default : + default : vfprintf(LOG_STREAM_STDOUT, msg, ap); fprintf(LOG_STREAM_STDOUT, "\n"); break; diff --git a/common/common.h b/common/common.h index 993d2923..54ef0b82 100644 --- a/common/common.h +++ b/common/common.h @@ -101,13 +101,15 @@ #define O_WRONLY _O_WRONLY #define O_RDONLY _O_RDONLY #define O_RDWR _O_RDWR - #define O_CREAT _O_CREAT + #define O_CREAT _O_CREAT #define O_EXCL _O_EXCL #define S_IRUSR _S_IREAD #define S_IWUSR _S_IWRITE #define PATH_SEP '\\' // --DSS needed for VS versions before 2010 - typedef __int8 int8_t; + #ifndef __MINGW32__ + typedef __int8 int8_t; + #endif typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; diff --git a/common/fko_util.c b/common/fko_util.c index 72cc2731..a520ffb3 100644 --- a/common/fko_util.c +++ b/common/fko_util.c @@ -566,7 +566,7 @@ char ns = calloc(1, len + 1); if(ns) { ns[len] = 0; - // strncpy to be pedantic about modification in multithreaded + // strncpy to be pedantic about modification in multithreaded // applications return strncpy(ns, s, len); } diff --git a/doc/README b/doc/README index 4bdf2cd2..d972ab55 100644 --- a/doc/README +++ b/doc/README @@ -36,5 +36,3 @@ For creating HTML versions of the man pages, simply use the "-f xhtml" option to the "a2x" command: a2x -f xhtml fwknopd.man.asciidoc - - diff --git a/doc/fwknop.man.asciidoc b/doc/fwknop.man.asciidoc index 9be94b57..606c8a29 100644 --- a/doc/fwknop.man.asciidoc +++ b/doc/fwknop.man.asciidoc @@ -514,7 +514,7 @@ SPA OPTIONS decryption. However, in some circumstances, if the clocks are out of sync and the user on the client system does not have the required access to change the local clock setting, it can be difficult to - construct and SPA packet with a time stamp the server will accept. + construct and SPA packet with a time stamp the server will accept. In this situation, the *--time-offset-plus* option can allow the user to specify an offset (e.g. ``60sec'' ``60min'' ``2days'' etc.) that is added to the local time. @@ -591,7 +591,7 @@ More comprehensive information on this can be found here: *--gpg-signer-key*='':: Specify the GnuPG key ID, e.g. ``+ABCD1234+'' (see the output of - "gpg --list-keys") or the key name to use when signing the SPA message. + "gpg --list-keys") or the key name to use when signing the SPA message. The user is prompted for the associated GnuPG password to create the signature. This adds a cryptographically strong mechanism to allow the *fwknopd* daemon on the remote server to authenticate who created @@ -616,7 +616,7 @@ home directory. This initial version has some sample directives that are commented out. It is up to the user to edit this file to meet their needs. The '.fwknoprc' file contains a default configuration area or stanza which -holds global configuration directives that override the program defaults. +holds global configuration directives that override the program defaults. You can edit this file and create additional 'named stanzas' that can be specified with the *-n* or *--named-config* option. Parameters defined in the named stanzas will override any matching 'default' stanza directives. diff --git a/doc/fwknopd.man.asciidoc b/doc/fwknopd.man.asciidoc index aa652adb..c19364fa 100644 --- a/doc/fwknopd.man.asciidoc +++ b/doc/fwknopd.man.asciidoc @@ -440,14 +440,14 @@ the '@sysconfdir@/fwknop/fwknopd.conf' file for additional details. *SYSLOG_FACILITY* '':: Override syslog facility. The ``SYSLOG_FACILITY'' variable can be set to one of ``LOG_LOCAL{0-7}'' or ``LOG_DAEMON'' (the default). - + *ENABLE_DESTINATION_RULE* '':: Controls whether *fwknopd* will set the destination field on the firewall - rule to the destination address specified on the incoming SPA packet. + rule to the destination address specified on the incoming SPA packet. This is useful for interfaces with multiple IP addresses hosting separate - services. If ``ENABLE_IPT_OUTPUT'' is set to ``Y'', the source field of - the firewall rule is set. FORWARD and SNAT rules are not affected however, - DNAT rules will also have their destination field set. The default is + services. If ``ENABLE_IPT_OUTPUT'' is set to ``Y'', the source field of + the firewall rule is set. FORWARD and SNAT rules are not affected however, + DNAT rules will also have their destination field set. The default is ``N'', which sets the destination field to 0.0.0.0/0 (any). *FWKNOP_RUN_DIR* '':: @@ -477,11 +477,11 @@ directive starts a new stanza. ``192.168.10.0/24''), and individual IP addresses can be specified as well. Also, multiple IP's and/or networks can be defined as a comma separated list (e.g. ``192.168.10.0/24,10.1.1.123'') - + *DESTINATION* '':: This defines the destination address for which the SPA packet will be accepted. The string ``ANY'' is also accepted if a valid SPA packet - should be honored to any destination IP. + should be honored to any destination IP. Networks should be specified in CIDR notation (e.g. ``192.168.10.0/24''), and individual IP addresses can be specified as well. Also, multiple IP's and/or networks can be defined as a comma separated list (e.g. diff --git a/doc/gpl-2.0.texi b/doc/gpl-2.0.texi index 150a5d10..015ae453 100644 --- a/doc/gpl-2.0.texi +++ b/doc/gpl-2.0.texi @@ -7,7 +7,7 @@ @center Version 2, June 1991 @c This file is intended to be included within another document, -@c hence no sectioning command or @node. +@c hence no sectioning command or @node. @display Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. diff --git a/doc/libfko.texi b/doc/libfko.texi index 4d56bdd9..534a38a1 100644 --- a/doc/libfko.texi +++ b/doc/libfko.texi @@ -113,7 +113,7 @@ Using libfko SPA Parameter Types -* Digests:: The message digest hashes supported by libfko +* Digests:: The message digest hashes supported by libfko * SPA Messages:: The fko @acronym{SPA} message types supported by libfko (and fwknop) * Encryption Algorithms:: Encryption schemes supported by libfko @@ -130,7 +130,7 @@ SPA Parameter Types @cindex Single Packet Authorization, intro The ``Firewall Knock Operator Library'' (libfko) is a C language library that -implements the functions needed to create and/or parse +implements the functions needed to create and/or parse @dfn{Single Packet Authorization} (@acronym{SPA}) data. It is designed to abstract the details of encoding, encryption, decoding, parsing, and verifying @acronym{SPA} messages such as those used by Michael Rash's @dfn{Firewall @@ -155,7 +155,7 @@ programs. @sp 1 @noindent For more information on fwknop and @acronym{SPA}, go to -@uref{http://www.cipherdyne.org/fwknop}. +@uref{http://www.cipherdyne.org/fwknop}. @menu * Getting Started:: Purpose of the manual, and how to use it @@ -521,7 +521,7 @@ fields that have a default value. This chapter provides the ``howto'' for using libfko, including required functions and parameter choices. In some sections, code samples are provided -to further illustrate usage. +to further illustrate usage. @menu * Creating Contexts:: Creating a new fko context @@ -963,7 +963,7 @@ use this function. However, some may find a reason to do it in this way. @deftypefun int fko_set_gpg_recipient (fko_ctx_t @var{ctx}, const char @var{recipient}); Sets the @acronym{GPG} key for the recipient. This would be the recipient's -public key used to encyrpt the @acronym{SPA} data. You can use the user name +public key used to encyrpt the @acronym{SPA} data. You can use the user name ("recip@@the.dest.com") or the key ID ("5EXXXXCC"). At present, multiple recipients are not supported. @end deftypefun @@ -1243,7 +1243,7 @@ called directly as it is called from @code{fko_spa_data_final}. @end deftypefun @deftypefun int fko_decode_spa_data (fko_ctx_t @var{ctx}); -This function performs the decoding, parsing, validation of the @acronym{SPA} +This function performs the decoding, parsing, validation of the @acronym{SPA} data that was just decrypted. It is normally not called directly as it is called from @code{fko_decrypt_spa_data} (which is in turn called from @code{fko_new_with_data} if a password is supplied to it). @@ -1467,9 +1467,9 @@ Invalid data: missing user data @item FKO_ERROR_INVALID_DATA_USER_FIRSTCHAR_VALIDFAIL Invalid data: user first char not valid @item FKO_ERROR_INVALID_DATA_USER_REMCHAR_VALIDFAIL -Invalid data: user remchar not valid +Invalid data: user remchar not valid @item FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN -Invalid data: util conversion to long less than minimum +Invalid data: util conversion to long less than minimum @item FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX Invalid data: util conversion to long greater than maximum @item FKO_ERROR_DATA_TOO_LARGE @@ -1586,7 +1586,7 @@ Invalid data: encrypt: GPG cipher failed @item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSG_NULL Invalid data: encrypt: GPG-encoded message is NULL @item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSGLEN_VALIDFAIL -Invalid data: encrypt: invalid GPG-encrypted message length +Invalid data: encrypt: invalid GPG-encrypted message length @end table @end deftypevar diff --git a/lib/base64.c b/lib/base64.c index 3a5fa14b..ced2553e 100644 --- a/lib/base64.c +++ b/lib/base64.c @@ -51,6 +51,11 @@ static unsigned char map2[] = }; #endif +#ifdef HAVE_C_UNIT_TESTS +#include "cunit_common.h" +DECLARE_TEST_SUITE(base64_test, "Utility functions test suite"); +#endif + int b64_decode(const char *in, unsigned char *out) { @@ -135,4 +140,113 @@ strip_b64_eq(char *data) *ndx = '\0'; } +#ifdef HAVE_C_UNIT_TESTS +DECLARE_UTEST(test_base64_encode, "test base64 encoding functions") +{ + char test_str[32] = {0}; + char test_out[32] = {0}; + char expected_out1[32] = {0}; + char expected_out2[32] = {0}; + char expected_out3[32] = {0}; + char expected_out4[32] = {0}; + char expected_out5[32] = {0}; + char expected_out6[32] = {0}; + char expected_out7[32] = {0}; + + strcpy(expected_out1, ""); + strcpy(expected_out2, "Zg=="); + strcpy(expected_out3, "Zm8="); + strcpy(expected_out4, "Zm9v"); + strcpy(expected_out5, "Zm9vYg=="); + strcpy(expected_out6, "Zm9vYmE="); + strcpy(expected_out7, "Zm9vYmFy"); + + strcpy(test_str, ""); + b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); + CU_ASSERT(strcmp(test_out, expected_out1) == 0); + + strcpy(test_str, "f"); + b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); + CU_ASSERT(strcmp(test_out, expected_out2) == 0); + + strcpy(test_str, "fo"); + b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); + CU_ASSERT(strcmp(test_out, expected_out3) == 0); + + strcpy(test_str, "foo"); + b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); + CU_ASSERT(strcmp(test_out, expected_out4) == 0); + + strcpy(test_str, "foob"); + b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); + CU_ASSERT(strcmp(test_out, expected_out5) == 0); + + strcpy(test_str, "fooba"); + b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); + CU_ASSERT(strcmp(test_out, expected_out6) == 0); + + strcpy(test_str, "foobar"); + b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); + CU_ASSERT(strcmp(test_out, expected_out7) == 0); + +} + +DECLARE_UTEST(test_base64_decode, "test base64 decoding functions") +{ + char test_str[32] = {0}; + char test_out[32] = {0}; + char expected_out1[32] = {0}; + char expected_out2[32] = {0}; + char expected_out3[32] = {0}; + char expected_out4[32] = {0}; + char expected_out5[32] = {0}; + char expected_out6[32] = {0}; + char expected_out7[32] = {0}; + + strcpy(expected_out1, ""); + strcpy(expected_out2, "f"); + strcpy(expected_out3, "fo"); + strcpy(expected_out4, "foo"); + strcpy(expected_out5, "foob"); + strcpy(expected_out6, "fooba"); + strcpy(expected_out7, "foobar"); + + strcpy(test_str, ""); + b64_decode(test_str, (unsigned char *)test_out); + CU_ASSERT(strcmp(test_out, expected_out1) == 0); + + strcpy(test_str, "Zg=="); + b64_decode(test_str, (unsigned char *)test_out); + CU_ASSERT(strcmp(test_out, expected_out2) == 0); + + strcpy(test_str, "Zm8="); + b64_decode(test_str, (unsigned char *)test_out); + CU_ASSERT(strcmp(test_out, expected_out3) == 0); + + strcpy(test_str, "Zm9v"); + b64_decode(test_str, (unsigned char *)test_out); + CU_ASSERT(strcmp(test_out, expected_out4) == 0); + + strcpy(test_str, "Zm9vYg=="); + b64_decode(test_str, (unsigned char *)test_out); + CU_ASSERT(strcmp(test_out, expected_out5) == 0); + + strcpy(test_str, "Zm9vYmE="); + b64_decode(test_str, (unsigned char *)test_out); + CU_ASSERT(strcmp(test_out, expected_out6) == 0); + + strcpy(test_str, "Zm9vYmFy"); + b64_decode(test_str, (unsigned char *)test_out); + CU_ASSERT(strcmp(test_out, expected_out7) == 0); +} + +int register_base64_test(void) +{ + ts_init(&TEST_SUITE(base64_test), TEST_SUITE_DESCR(base64_test), NULL, NULL); + ts_add_utest(&TEST_SUITE(base64_test), UTEST_FCT(test_base64_encode), UTEST_DESCR(test_base64_encode)); + ts_add_utest(&TEST_SUITE(base64_test), UTEST_FCT(test_base64_decode), UTEST_DESCR(test_base64_decode)); + + return register_ts(&TEST_SUITE(base64_test)); +} +#endif /***EOF***/ diff --git a/lib/fko_common.h b/lib/fko_common.h index efa710da..4cb6aa86 100644 --- a/lib/fko_common.h +++ b/lib/fko_common.h @@ -72,7 +72,7 @@ #define O_WRONLY _O_WRONLY #define O_RDONLY _O_RDONLY #define O_RDWR _O_RDWR - #define O_CREAT _O_CREAT + #define O_CREAT _O_CREAT #define O_EXCL _O_EXCL #define S_IRUSR _S_IREAD #define S_IWUSR _S_IWRITE diff --git a/lib/fko_context.h b/lib/fko_context.h index ef249e6d..09af71b1 100644 --- a/lib/fko_context.h +++ b/lib/fko_context.h @@ -88,7 +88,7 @@ struct fko_context { char *digest; int digest_len; /*@}*/ - /** \name Digest of raw encrypted/base64 data + /** \name Digest of raw encrypted/base64 data * This is used for replay attack detection */ /*@{*/ diff --git a/lib/fko_decode.c b/lib/fko_decode.c index 1dc6dd57..81dd036b 100644 --- a/lib/fko_decode.c +++ b/lib/fko_decode.c @@ -599,7 +599,7 @@ DECLARE_UTEST(num_fields, "Count the number of SPA fields in a SPA packet") /* Zeroing the spa packet */ memset(spa_packet, 0, sizeof(spa_packet)); - + /* Check we are able to count the number of SPA fields */ for(ix_field=0 ; ix_field<=MAX_SPA_FIELDS+2 ; ix_field++) { @@ -623,7 +623,7 @@ DECLARE_UTEST(last_field, "Count the number of bytes to the last :") /* Zeroing the spa packet */ memset(spa_packet, 0, sizeof(spa_packet)); - + /* Check for a valid count when the number of field is less than MAX_SPA_FIELDS */ CU_ASSERT(last_field("a:") == 2); CU_ASSERT(last_field("ab:abc:") == 7); diff --git a/lib/fko_state.h b/lib/fko_state.h index bc740c33..58689197 100644 --- a/lib/fko_state.h +++ b/lib/fko_state.h @@ -72,7 +72,7 @@ typedef enum { #define FKO_SPA_DATA_MODIFIED ( \ FKO_DATA_MODIFIED | FKO_SPA_MSG_TYPE_MODIFIED \ | FKO_DIGEST_TYPE_MODIFIED | FKO_ENCRYPT_TYPE_MODIFIED ) - + /* This should return true if any SPA data field has been modifed since the * last encode/encrypt. */ diff --git a/lib/fko_utests.c b/lib/fko_utests.c index a9f22b3c..2895500f 100755 --- a/lib/fko_utests.c +++ b/lib/fko_utests.c @@ -22,6 +22,7 @@ static void register_test_suites(void) register_ts_digest_test(); register_ts_aes_test(); register_utils_test(); + register_base64_test(); } /* The main() function for setting up and running the tests. diff --git a/lib/hmac.c b/lib/hmac.c index 73e2afa0..c9b98069 100644 --- a/lib/hmac.c +++ b/lib/hmac.c @@ -32,46 +32,12 @@ #ifdef HAVE_C_UNIT_TESTS DECLARE_TEST_SUITE(hmac_test, "hmac functions test suite"); #endif -typedef struct { - MD5Context ctx_inside; - MD5Context ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_md5_ctx; - -typedef struct { - SHA1_INFO ctx_inside; - SHA1_INFO ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha1_ctx; - -typedef struct { - SHA256_CTX ctx_inside; - SHA256_CTX ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha256_ctx; - -typedef struct { - SHA384_CTX ctx_inside; - SHA384_CTX ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha384_ctx; - -typedef struct { - SHA512_CTX ctx_inside; - SHA512_CTX ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha512_ctx; +/** + * /brief populate the inner and outer pads + * + * + */ static void pad_init(unsigned char *inner_pad, unsigned char *outer_pad, const unsigned char * const key, const int key_len) @@ -95,353 +61,218 @@ pad_init(unsigned char *inner_pad, unsigned char *outer_pad, return; } -/* Begin MD5 HMAC functions -*/ -static void -hmac_md5_init(hmac_md5_ctx *ctx, const char *key, const int key_len) +void +hmac_md5(const char *msg, const unsigned int msg_len, + unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - unsigned char init_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; + unsigned char inner_hash[MD5_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[MD5_BLOCK_LEN + MD5_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memcpy(init_key, key, final_len); + int final_len = hmac_key_len; - if(MD5_BLOCK_LEN < key_len) + if(MD5_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ - md5(final_key, init_key, final_len); + md5(final_key, (unsigned char *)hmac_key, final_len); + final_len = MD5_DIGEST_LEN; } else { - memcpy(final_key, init_key, key_len); + memcpy(final_key, hmac_key, hmac_key_len); } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, MD5_BLOCK_LEN); + memcpy(padded_msg + MD5_BLOCK_LEN, msg, msg_len); - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - MD5Init(&ctx->ctx_inside); - MD5Update(&ctx->ctx_inside, ctx->block_inner_pad, MD5_BLOCK_LEN); - - MD5Init(&ctx->ctx_outside); - MD5Update(&ctx->ctx_outside, ctx->block_outer_pad, MD5_BLOCK_LEN); - - return; -} - -static void -hmac_md5_update(hmac_md5_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - MD5Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} + //Calculate the inner hash + md5(inner_hash, padded_msg, msg_len + MD5_BLOCK_LEN); -static void -hmac_md5_final(hmac_md5_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[MD5_DIGEST_LEN]; + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, MD5_BLOCK_LEN); + memcpy(padded_hash + MD5_BLOCK_LEN, inner_hash, MD5_DIGEST_LEN); - MD5Final(digest_inside, &ctx->ctx_inside); - MD5Update(&ctx->ctx_outside, digest_inside, MD5_DIGEST_LEN); - MD5Final(hmac, &ctx->ctx_outside); + //the outer hash is the final hmac + md5(hmac, padded_hash, MD5_BLOCK_LEN + MD5_DIGEST_LEN); + free(padded_msg); return; } void -hmac_md5(const char *msg, const unsigned int msg_len, +hmac_sha1(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_md5_ctx ctx; - - memset(&ctx, 0, sizeof(ctx)); - - hmac_md5_init(&ctx, hmac_key, hmac_key_len); - hmac_md5_update(&ctx, msg, msg_len); - hmac_md5_final(&ctx, hmac); - - return; -} - -/* Begin SHA1 HMAC functions -*/ -static void -hmac_sha1_init(hmac_sha1_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - unsigned char init_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; + unsigned char inner_hash[SHA1_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA1_BLOCK_LEN + SHA1_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memcpy(init_key, key, final_len); + int final_len = hmac_key_len; - if(SHA1_BLOCK_LEN < key_len) + if(SHA1_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ - sha1(final_key, init_key, final_len); + sha1(final_key, (unsigned char *)hmac_key, final_len); + final_len = SHA1_DIGEST_LEN; } else { - memcpy(final_key, init_key, key_len); + memcpy(final_key, hmac_key, hmac_key_len); } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA1_BLOCK_LEN); + memcpy(padded_msg + SHA1_BLOCK_LEN, msg, msg_len); - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - sha1_init(&ctx->ctx_inside); - sha1_update(&ctx->ctx_inside, ctx->block_inner_pad, SHA1_BLOCK_LEN); - - sha1_init(&ctx->ctx_outside); - sha1_update(&ctx->ctx_outside, ctx->block_outer_pad, SHA1_BLOCK_LEN); - - return; -} - -static void -hmac_sha1_update(hmac_sha1_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - sha1_update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} + //Calculate the inner hash + sha1(inner_hash, padded_msg, msg_len + SHA1_BLOCK_LEN); -static void -hmac_sha1_final(hmac_sha1_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA1_DIGEST_LEN]; + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA1_BLOCK_LEN); + memcpy(padded_hash + SHA1_BLOCK_LEN, inner_hash, SHA1_DIGEST_LEN); - sha1_final(digest_inside, &ctx->ctx_inside); - sha1_update(&ctx->ctx_outside, digest_inside, SHA1_DIGEST_LEN); - sha1_final(hmac, &ctx->ctx_outside); + //the outer hash is the final hmac + sha1(hmac, padded_hash, SHA1_BLOCK_LEN + SHA1_DIGEST_LEN); + free(padded_msg); return; } void -hmac_sha1(const char *msg, const unsigned int msg_len, +hmac_sha256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_sha1_ctx ctx; - - memset(&ctx, 0, sizeof(ctx)); - - hmac_sha1_init(&ctx, hmac_key, hmac_key_len); - hmac_sha1_update(&ctx, msg, msg_len); - hmac_sha1_final(&ctx, hmac); - - return; -} - -/* Begin SHA256 HMAC functions -*/ -static void -hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - unsigned char init_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; + unsigned char inner_hash[SHA256_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA256_BLOCK_LEN + SHA256_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memcpy(init_key, key, final_len); + int final_len = hmac_key_len; - if(SHA256_BLOCK_LEN < key_len) + if(SHA256_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ - sha256(final_key, init_key, final_len); + sha256(final_key, (unsigned char *)hmac_key, final_len); + final_len = SHA256_DIGEST_LEN; } else { - memcpy(final_key, init_key, key_len); + memcpy(final_key, hmac_key, hmac_key_len); } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA256_BLOCK_LEN); + memcpy(padded_msg + SHA256_BLOCK_LEN, msg, msg_len); - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - SHA256_Init(&ctx->ctx_inside); - SHA256_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA256_BLOCK_LEN); - - SHA256_Init(&ctx->ctx_outside); - SHA256_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA256_BLOCK_LEN); - - return; -} - -static void -hmac_sha256_update(hmac_sha256_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - SHA256_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} + //Calculate the inner hash + sha256(inner_hash, padded_msg, msg_len + SHA256_BLOCK_LEN); -static void -hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA256_DIGEST_LEN]; + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA256_BLOCK_LEN); + memcpy(padded_hash + SHA256_BLOCK_LEN, inner_hash, SHA256_DIGEST_LEN); - SHA256_Final(digest_inside, &ctx->ctx_inside); - SHA256_Update(&ctx->ctx_outside, digest_inside, SHA256_DIGEST_LEN); - SHA256_Final(hmac, &ctx->ctx_outside); + //the outer hash is the final hmac + sha256(hmac, padded_hash, SHA256_BLOCK_LEN + SHA256_DIGEST_LEN); + free(padded_msg); return; } void -hmac_sha256(const char *msg, const unsigned int msg_len, +hmac_sha384(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_sha256_ctx ctx; - - memset(&ctx, 0, sizeof(ctx)); - - hmac_sha256_init(&ctx, hmac_key, hmac_key_len); - hmac_sha256_update(&ctx, msg, msg_len); - hmac_sha256_final(&ctx, hmac); - - return; -} - -/* Begin SHA384 HMAC functions -*/ -static void -hmac_sha384_init(hmac_sha384_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; + unsigned char inner_hash[SHA384_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA384_BLOCK_LEN + SHA384_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; + int final_len = hmac_key_len; - if(SHA384_BLOCK_LEN < key_len) + if(SHA384_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ - sha384(final_key, (unsigned char *)key, final_len); + sha384(final_key, (unsigned char *)hmac_key, final_len); + final_len = SHA384_DIGEST_LEN; } else { - memcpy(final_key, key, key_len); + memcpy(final_key, hmac_key, hmac_key_len); } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA384_BLOCK_LEN); + memcpy(padded_msg + SHA384_BLOCK_LEN, msg, msg_len); - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - SHA384_Init(&ctx->ctx_inside); - SHA384_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA384_BLOCK_LEN); - - SHA384_Init(&ctx->ctx_outside); - SHA384_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA384_BLOCK_LEN); - - return; -} - -static void -hmac_sha384_update(hmac_sha384_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - SHA384_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} + //Calculate the inner hash + sha384(inner_hash, padded_msg, msg_len + SHA384_BLOCK_LEN); -static void -hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA384_DIGEST_LEN]; + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA384_BLOCK_LEN); + memcpy(padded_hash + SHA384_BLOCK_LEN, inner_hash, SHA384_DIGEST_LEN); - SHA384_Final(digest_inside, &ctx->ctx_inside); - SHA384_Update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_LEN); - SHA384_Final(hmac, &ctx->ctx_outside); + //the outer hash is the final hmac + sha384(hmac, padded_hash, SHA384_BLOCK_LEN + SHA384_DIGEST_LEN); + free(padded_msg); return; } void -hmac_sha384(const char *msg, const unsigned int msg_len, +hmac_sha512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_sha384_ctx ctx; - - memset(&ctx, 0, sizeof(ctx)); - - hmac_sha384_init(&ctx, hmac_key, hmac_key_len); - hmac_sha384_update(&ctx, msg, msg_len); - hmac_sha384_final(&ctx, hmac); - - return; -} - -/* Begin SHA512 HMAC functions -*/ -static void -hmac_sha512_init(hmac_sha512_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; + unsigned char inner_hash[SHA512_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA512_BLOCK_LEN + SHA512_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; + int final_len = hmac_key_len; - if(SHA512_BLOCK_LEN < key_len) + if(SHA512_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ - sha512(final_key, (unsigned char *)key, final_len); + sha512(final_key, (unsigned char *)hmac_key, final_len); final_len = SHA512_DIGEST_LEN; } else { - memcpy(final_key, key, key_len); + memcpy(final_key, hmac_key, hmac_key_len); } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA512_BLOCK_LEN); + memcpy(padded_msg + SHA512_BLOCK_LEN, msg, msg_len); - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - SHA512_Init(&ctx->ctx_inside); - SHA512_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA512_BLOCK_LEN); - - SHA512_Init(&ctx->ctx_outside); - SHA512_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA512_BLOCK_LEN); - - return; -} - -static void -hmac_sha512_update(hmac_sha512_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - SHA512_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} - -static void -hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA512_DIGEST_LEN]; - - SHA512_Final(digest_inside, &ctx->ctx_inside); - SHA512_Update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_LEN); - SHA512_Final(hmac, &ctx->ctx_outside); - - return; -} - -void -hmac_sha512(const char *msg, const unsigned int msg_len, - unsigned char *hmac, const char *hmac_key, const int hmac_key_len) -{ - hmac_sha512_ctx ctx; + //Calculate the inner hash + sha512(inner_hash, padded_msg, msg_len + SHA512_BLOCK_LEN); - memset(&ctx, 0, sizeof(ctx)); + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA512_BLOCK_LEN); + memcpy(padded_hash + SHA512_BLOCK_LEN, inner_hash, SHA512_DIGEST_LEN); - hmac_sha512_init(&ctx, hmac_key, hmac_key_len); - hmac_sha512_update(&ctx, msg, msg_len); - hmac_sha512_final(&ctx, hmac); + //the outer hash is the final hmac + sha512(hmac, padded_hash, SHA512_BLOCK_LEN + SHA512_DIGEST_LEN); + free(padded_msg); return; } diff --git a/lib/hmac.h b/lib/hmac.h index a5fb4785..9e81e36c 100644 --- a/lib/hmac.h +++ b/lib/hmac.h @@ -32,7 +32,7 @@ #include "digest.h" -#define MAX_DIGEST_BLOCK_LEN SHA3_256_BLOCK_LEN +#define MAX_DIGEST_BLOCK_LEN SHA3_256_BLOCK_LEN /**< The longest block length is from SHA3_256 */ /** * \brief Generate MD5 based HMAC * @@ -47,16 +47,88 @@ */ void hmac_md5(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); +/** + * \brief Generate SHA1 based HMAC + * + * This function generates an HMAC verification hash, based on SHA1 + * + * \param msg Pointer to the message to be signed + * \param msg_len size of the message string + * \param hmac Pointer to the hmac buffer, where the final hmac will be stored + * \param hmac_key Pointer to the key to be used for generating the hmac + * \param hmac_key_len Size of the hmac key + * + */ void hmac_sha1(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); +/** + * \brief Generate SHA256 based HMAC + * + * This function generates an HMAC verification hash, based on SHA256 + * + * \param msg Pointer to the message to be signed + * \param msg_len size of the message string + * \param hmac Pointer to the hmac buffer, where the final hmac will be stored + * \param hmac_key Pointer to the key to be used for generating the hmac + * \param hmac_key_len Size of the hmac key + * + */ void hmac_sha256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); +/** + * \brief Generate SHA384 based HMAC + * + * This function generates an HMAC verification hash, based on SHA384 + * + * \param msg Pointer to the message to be signed + * \param msg_len size of the message string + * \param hmac Pointer to the hmac buffer, where the final hmac will be stored + * \param hmac_key Pointer to the key to be used for generating the hmac + * \param hmac_key_len Size of the hmac key + * + */ void hmac_sha384(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); +/** + * \brief Generate SHA512 based HMAC + * + * This function generates an HMAC verification hash, based on SHA512 + * + * \param msg Pointer to the message to be signed + * \param msg_len size of the message string + * \param hmac Pointer to the hmac buffer, where the final hmac will be stored + * \param hmac_key Pointer to the key to be used for generating the hmac + * \param hmac_key_len Size of the hmac key + * + */ void hmac_sha512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); +/** + * \brief Generate SHA3-256 based HMAC + * + * This function generates an HMAC verification hash, based on SHA3-256 + * + * \param msg Pointer to the message to be signed + * \param msg_len size of the message string + * \param hmac Pointer to the hmac buffer, where the final hmac will be stored + * \param hmac_key Pointer to the key to be used for generating the hmac + * \param hmac_key_len Size of the hmac key + * + */ void hmac_sha3_256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); +/** + * \brief Generate SHA3-512 based HMAC + * + * This function generates an HMAC verification hash, based on SHA3-512 + * + * \param msg Pointer to the message to be signed + * \param msg_len size of the message string + * \param hmac Pointer to the hmac buffer, where the final hmac will be stored + * \param hmac_key Pointer to the key to be used for generating the hmac + * \param hmac_key_len Size of the hmac key + * + */ void hmac_sha3_512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); diff --git a/lib/md5.c b/lib/md5.c index 0d410396..f8f864f7 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -118,7 +118,7 @@ MD5Update(MD5Context *ctx, unsigned char *buf, unsigned len) memcpy(ctx->in, buf, len); } -/* Final wrapup - pad to 64-byte boundary with the bit pattern +/* Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void @@ -272,6 +272,6 @@ MD5Transform(uint32_t buf[4], uint32_t in[16]) buf[1] += b; buf[2] += c; buf[3] += d; -} +} /***EOF***/ diff --git a/lib/rijndael.c b/lib/rijndael.c index 8b4df171..d8dda048 100644 --- a/lib/rijndael.c +++ b/lib/rijndael.c @@ -191,7 +191,7 @@ uint8_t sbox[256] = { 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, - 22, + 22, }; uint8_t isbox[256] = { @@ -212,7 +212,7 @@ uint8_t isbox[256] = { 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, - 125, + 125, }; /* Used only by the key schedule */ @@ -486,7 +486,7 @@ block_encrypt(RIJNDAEL_context *ctx, uint8_t *input, int inputlen, /* set initial value */ memcpy(block, iv, RIJNDAEL_BLOCKSIZE); for (i=0; i< nblocks; i++) { - for (j=0; j