From f4b23653ced61fd78145e411614c56b8e162c3b5 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Sun, 3 Oct 2021 14:30:36 +0200 Subject: [PATCH 1/4] changed mezhjod / request id of rpc functions to be md5 hash instead of uint32_t --- Makefile | 2 +- erpc_c/infra/erpc_basic_codec.cpp | 28 +- erpc_c/infra/erpc_basic_codec.h | 4 +- erpc_c/infra/erpc_client_manager.cpp | 6 +- erpc_c/infra/erpc_client_manager.h | 4 +- erpc_c/infra/erpc_codec.h | 18 +- erpc_c/infra/erpc_server.cpp | 8 +- erpc_c/infra/erpc_server.h | 6 +- erpc_c/infra/erpc_simple_server.cpp | 6 +- erpc_c/infra/erpc_simple_server.h | 4 +- erpc_c/infra/erpc_transport_arbitrator.cpp | 4 +- erpc_c/port/erpc_threading_pthreads.cpp | 6 +- erpcgen/Makefile | 1 + erpcgen/src/CGenerator.cpp | 4 +- erpcgen/src/Generator.cpp | 2 +- erpcgen/src/PythonGenerator.cpp | 3 +- erpcgen/src/md5.cpp | 362 ++++++++++++++++++ erpcgen/src/md5.h | 93 +++++ .../src/templates/c_common_header.template | 9 +- .../src/templates/c_server_header.template | 2 +- .../src/templates/c_server_source.template | 26 +- 21 files changed, 532 insertions(+), 66 deletions(-) create mode 100644 erpcgen/src/md5.cpp create mode 100644 erpcgen/src/md5.h diff --git a/Makefile b/Makefile index 5dca3bf6..cc947963 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ include mk/erpc_common.mk #.NOTPARALLEL: ifeq "$(is_linux)" "1" -ERPCSNIFFER = erpcsniffer +#ERPCSNIFFER = erpcsniffer endif # Subdirectories to run make on. diff --git a/erpc_c/infra/erpc_basic_codec.cpp b/erpc_c/infra/erpc_basic_codec.cpp index 38c2c521..132d3d26 100644 --- a/erpc_c/infra/erpc_basic_codec.cpp +++ b/erpc_c/infra/erpc_basic_codec.cpp @@ -19,18 +19,22 @@ using namespace erpc; + //////////////////////////////////////////////////////////////////////////////// // Code //////////////////////////////////////////////////////////////////////////////// const uint8_t BasicCodec::kBasicCodecVersion = 1; -void BasicCodec::startWriteMessage(message_type_t type, uint32_t service, uint32_t request, uint32_t sequence) +void BasicCodec::startWriteMessage(message_type_t type, uint32_t service, const Md5Hash request, uint32_t sequence) { - uint32_t header = (kBasicCodecVersion << 24) | ((service & 0xff) << 16) | ((request & 0xff) << 8) | (type & 0xff); - - write(header); + Header header(kBasicCodecVersion, + static_cast((service & 0xff)), + request, + type + ); + writeData(&header, sizeof(Header)); write(sequence); } @@ -178,25 +182,25 @@ void BasicCodec::writeCallback(funPtr callback1, funPtr callback2) } } -void BasicCodec::startReadMessage(message_type_t *type, uint32_t *service, uint32_t *request, uint32_t *sequence) +void BasicCodec::startReadMessage(message_type_t *type, uint32_t *service, Md5Hash request, uint32_t *sequence) { - uint32_t header; + Header header; + readData(&header, sizeof(Header)); - read(&header); - - if (((header >> 24) & 0xffU) != kBasicCodecVersion) + if (header.codecVersion != kBasicCodecVersion) { updateStatus(kErpcStatus_InvalidMessageVersion); } if (!m_status) { - *service = ((header >> 16) & 0xffU); - *request = ((header >> 8) & 0xffU); - *type = static_cast(header & 0xffU); + *service = header.service; + std::memcpy(request, header.id, sizeof(Md5Hash)); + *type = static_cast(header.type); read(sequence); } + } void BasicCodec::readData(void *value, uint32_t length) diff --git a/erpc_c/infra/erpc_basic_codec.h b/erpc_c/infra/erpc_basic_codec.h index 8fb44d0d..c5ef288b 100644 --- a/erpc_c/infra/erpc_basic_codec.h +++ b/erpc_c/infra/erpc_basic_codec.h @@ -59,7 +59,7 @@ class BasicCodec : public Codec * @param[in] sequence Send sequence number to be sure that * received message is reply for current request. or write function. */ - virtual void startWriteMessage(message_type_t type, uint32_t service, uint32_t request, uint32_t sequence) override; + virtual void startWriteMessage(message_type_t type, uint32_t service, const Md5Hash request, uint32_t sequence) override; /*! * @brief Prototype for write data stream. @@ -219,7 +219,7 @@ class BasicCodec : public Codec * @param[out] sequence Returned sequence number to be sure that * received message is reply for current request. */ - virtual void startReadMessage(message_type_t *type, uint32_t *service, uint32_t *request, + virtual void startReadMessage(message_type_t *type, uint32_t *service, Md5Hash request, uint32_t *sequence) override; /*! diff --git a/erpc_c/infra/erpc_client_manager.cpp b/erpc_c/infra/erpc_client_manager.cpp index 65e162ca..ef4eb2d6 100644 --- a/erpc_c/infra/erpc_client_manager.cpp +++ b/erpc_c/infra/erpc_client_manager.cpp @@ -169,7 +169,7 @@ void ClientManager::verifyReply(RequestContext &request) { message_type_t msgType; uint32_t service; - uint32_t requestNumber; + Md5Hash requestNumber; uint32_t sequence; // Some transport layers change the request's message buffer pointer (for things like zero @@ -177,7 +177,7 @@ void ClientManager::verifyReply(RequestContext &request) request.getCodec()->reset(); // Extract the reply header. - request.getCodec()->startReadMessage(&msgType, &service, &requestNumber, &sequence); + request.getCodec()->startReadMessage(&msgType, &service, requestNumber, &sequence); if (request.getCodec()->isStatusOk() == true) { @@ -218,7 +218,7 @@ void ClientManager::releaseRequest(RequestContext &request) m_codecFactory->dispose(request.getCodec()); } -void ClientManager::callErrorHandler(erpc_status_t err, uint32_t functionID) +void ClientManager::callErrorHandler(erpc_status_t err, const Md5Hash functionID) { if (m_errorHandler != NULL) { diff --git a/erpc_c/infra/erpc_client_manager.h b/erpc_c/infra/erpc_client_manager.h index c779db36..0007d019 100644 --- a/erpc_c/infra/erpc_client_manager.h +++ b/erpc_c/infra/erpc_client_manager.h @@ -30,7 +30,7 @@ extern "C" { #endif typedef void (*client_error_handler_t)(erpc_status_t err, - uint32_t functionID); /*!< eRPC error handler function type. */ + const Md5Hash functionID); /*!< eRPC error handler function type. */ #ifdef __cplusplus } @@ -136,7 +136,7 @@ class ClientManager : public ClientServerCommon * @param[in] err Specify function status at the end of eRPC call. * @param[in] functionID Specify eRPC function call. */ - void callErrorHandler(erpc_status_t err, uint32_t functionID); + void callErrorHandler(erpc_status_t err, const Md5Hash functionID); #if ERPC_NESTED_CALLS /*! diff --git a/erpc_c/infra/erpc_codec.h b/erpc_c/infra/erpc_codec.h index f5861f31..b87ddb03 100644 --- a/erpc_c/infra/erpc_codec.h +++ b/erpc_c/infra/erpc_codec.h @@ -43,6 +43,20 @@ typedef enum _message_type typedef void *funPtr; // Pointer to functions typedef funPtr *arrayOfFunPtr; // Pointer to array of functions +using Md5Hash = char[33]; + +struct Header{ + const uint8_t codecVersion = 0; + uint8_t service = 0; + char id[32]; + uint8_t type = 0; + Header(){} + Header(const uint8_t version, uint8_t service, const Md5Hash hash, message_type_t type) : codecVersion(version), service(service), type(static_cast(type & 0xff)){ + std::memcpy(id, hash, sizeof(Md5Hash)-1); + } +}; + + /*! * @brief Abstract serialization encoder/decoder interface. * @@ -135,7 +149,7 @@ class Codec * @param[in] sequence Send sequence number to be sure that * received message is reply for current request. */ - virtual void startWriteMessage(message_type_t type, uint32_t service, uint32_t request, uint32_t sequence) = 0; + virtual void startWriteMessage(message_type_t type, uint32_t service, const Md5Hash request, uint32_t sequence) = 0; /*! * @brief Prototype for write boolean value. @@ -287,7 +301,7 @@ class Codec * @param[in] sequence Returned sequence number to be sure that * received message is reply for current request. */ - virtual void startReadMessage(message_type_t *type, uint32_t *service, uint32_t *request, uint32_t *sequence) = 0; + virtual void startReadMessage(message_type_t *type, uint32_t *service, Md5Hash request, uint32_t *sequence) = 0; /*! * @brief Prototype for read boolean value. diff --git a/erpc_c/infra/erpc_server.cpp b/erpc_c/infra/erpc_server.cpp index 4c9c0fec..593c559c 100644 --- a/erpc_c/infra/erpc_server.cpp +++ b/erpc_c/infra/erpc_server.cpp @@ -69,14 +69,14 @@ void Server::removeService(Service *service) } } -erpc_status_t Server::readHeadOfMessage(Codec *codec, message_type_t &msgType, uint32_t &serviceId, uint32_t &methodId, - uint32_t &sequence) +erpc_status_t Server::readHeadOfMessage(Codec *codec, message_type_t &msgType, uint32_t &serviceId, Md5Hash methodId, + uint32_t& sequence) { - codec->startReadMessage(&msgType, &serviceId, &methodId, &sequence); + codec->startReadMessage(&msgType, &serviceId, methodId, &sequence); return codec->getStatus(); } -erpc_status_t Server::processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, +erpc_status_t Server::processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence) { erpc_status_t err = kErpcStatus_Success; diff --git a/erpc_c/infra/erpc_server.h b/erpc_c/infra/erpc_server.h index 4bc2003a..5e6f07e2 100644 --- a/erpc_c/infra/erpc_server.h +++ b/erpc_c/infra/erpc_server.h @@ -87,7 +87,7 @@ class Service * * @return Based on handleInvocation implementation. */ - virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, Codec *codec, + virtual erpc_status_t handleInvocation(Md5Hash methodId, uint32_t sequence, Codec *codec, MessageBufferFactory *messageFactory) = 0; protected: @@ -186,7 +186,7 @@ class Server : public ClientServerCommon * * @returns #kErpcStatus_Success or based on codec startReadMessage. */ - virtual erpc_status_t processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, + virtual erpc_status_t processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence); /*! @@ -201,7 +201,7 @@ class Server : public ClientServerCommon * @returns #kErpcStatus_Success or based on service handleInvocation. */ virtual erpc_status_t readHeadOfMessage(Codec *codec, message_type_t &msgType, uint32_t &serviceId, - uint32_t &methodId, uint32_t &sequence); + Md5Hash methodId, uint32_t &sequence); /*! * @brief This function finds service base on service ID. diff --git a/erpc_c/infra/erpc_simple_server.cpp b/erpc_c/infra/erpc_simple_server.cpp index 39f43a2d..691fcd96 100644 --- a/erpc_c/infra/erpc_simple_server.cpp +++ b/erpc_c/infra/erpc_simple_server.cpp @@ -36,7 +36,7 @@ erpc_status_t SimpleServer::runInternal(void) // Handle the request. message_type_t msgType; uint32_t serviceId; - uint32_t methodId; + Md5Hash methodId; uint32_t sequence; erpc_status_t err = runInternalBegin(&codec, buff, msgType, serviceId, methodId, sequence); @@ -49,7 +49,7 @@ erpc_status_t SimpleServer::runInternal(void) } erpc_status_t SimpleServer::runInternalBegin(Codec **codec, MessageBuffer &buff, message_type_t &msgType, - uint32_t &serviceId, uint32_t &methodId, uint32_t &sequence) + uint32_t &serviceId, Md5Hash methodId, uint32_t &sequence) { erpc_status_t err = kErpcStatus_Success; @@ -116,7 +116,7 @@ erpc_status_t SimpleServer::runInternalBegin(Codec **codec, MessageBuffer &buff, return err; } -erpc_status_t SimpleServer::runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, +erpc_status_t SimpleServer::runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence) { erpc_status_t err = processMessage(codec, msgType, serviceId, methodId, sequence); diff --git a/erpc_c/infra/erpc_simple_server.h b/erpc_c/infra/erpc_simple_server.h index 651f7270..761a8190 100644 --- a/erpc_c/infra/erpc_simple_server.h +++ b/erpc_c/infra/erpc_simple_server.h @@ -79,7 +79,7 @@ class SimpleServer : public Server * @returns #kErpcStatus_Success or based on service handleInvocation. */ erpc_status_t runInternalBegin(Codec **codec, MessageBuffer &buff, message_type_t &msgType, uint32_t &serviceId, - uint32_t &methodId, uint32_t &sequence); + Md5Hash methodId, uint32_t &sequence); /*! * @brief This function process message and handle sending respond. @@ -92,7 +92,7 @@ class SimpleServer : public Server * * @returns #kErpcStatus_Success or based on service handleInvocation. */ - erpc_status_t runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, + erpc_status_t runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence); #if ERPC_NESTED_CALLS diff --git a/erpc_c/infra/erpc_transport_arbitrator.cpp b/erpc_c/infra/erpc_transport_arbitrator.cpp index 23f096cf..b69671f5 100644 --- a/erpc_c/infra/erpc_transport_arbitrator.cpp +++ b/erpc_c/infra/erpc_transport_arbitrator.cpp @@ -66,7 +66,7 @@ erpc_status_t TransportArbitrator::receive(MessageBuffer *message) erpc_status_t err; message_type_t msgType; uint32_t service; - uint32_t requestNumber; + Md5Hash requestNumber; uint32_t sequence; PendingClientInfo *client; @@ -94,7 +94,7 @@ erpc_status_t TransportArbitrator::receive(MessageBuffer *message) m_codec->setBuffer(*message); // Parse the message header. - m_codec->startReadMessage(&msgType, &service, &requestNumber, &sequence); + m_codec->startReadMessage(&msgType, &service, requestNumber, &sequence); err = m_codec->getStatus(); if (err != kErpcStatus_Success) { diff --git a/erpc_c/port/erpc_threading_pthreads.cpp b/erpc_c/port/erpc_threading_pthreads.cpp index 3586013c..5107caea 100644 --- a/erpc_c/port/erpc_threading_pthreads.cpp +++ b/erpc_c/port/erpc_threading_pthreads.cpp @@ -44,23 +44,25 @@ Thread::Thread(const char *name) { } -Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name) +Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name, thread_stack_pointer ptr) : m_name(name) , m_entry(entry) , m_arg(0) , m_stackSize(stackSize) , m_priority(priority) , m_thread(0) +,m_stackPtr(ptr) { } Thread::~Thread(void) {} -void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize) +void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize, thread_stack_pointer ptr) { m_entry = entry; m_stackSize = stackSize; m_priority = priority; + m_stackPtr = ptr; } void Thread::start(void *arg) diff --git a/erpcgen/Makefile b/erpcgen/Makefile index 744736a6..db2c874e 100644 --- a/erpcgen/Makefile +++ b/erpcgen/Makefile @@ -58,6 +58,7 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \ $(ERPC_ROOT)/erpcgen/src/UniqueIdChecker.cpp \ $(ERPC_ROOT)/erpcgen/src/CGenerator.cpp \ $(ERPC_ROOT)/erpcgen/src/PythonGenerator.cpp \ + $(ERPC_ROOT)/erpcgen/src/md5.cpp \ $(ERPC_ROOT)/erpcgen/src/erpcgen.cpp \ $(ERPC_ROOT)/erpcgen/src/ErpcLexer.cpp \ $(ERPC_ROOT)/erpcgen/src/Generator.cpp \ diff --git a/erpcgen/src/CGenerator.cpp b/erpcgen/src/CGenerator.cpp index 6b732e45..6ade6baa 100644 --- a/erpcgen/src/CGenerator.cpp +++ b/erpcgen/src/CGenerator.cpp @@ -13,11 +13,13 @@ #include "ParseErrors.h" #include "annotations.h" #include "format_string.h" +#include "md5.h" #include #include #include + using namespace erpcgen; using namespace cpptempl; using namespace std; @@ -1692,7 +1694,7 @@ data_map CGenerator::getFunctionTemplateData(Group *group, Function *fn) string proto = getFunctionPrototype(group, fn); info["prototype"] = proto; info["name"] = getOutputName(fn); - info["id"] = fn->getUniqueId(); + info["id"] = md5(proto); return info; } diff --git a/erpcgen/src/Generator.cpp b/erpcgen/src/Generator.cpp index cfd4c538..08ac4c75 100644 --- a/erpcgen/src/Generator.cpp +++ b/erpcgen/src/Generator.cpp @@ -406,7 +406,7 @@ data_list Generator::makeGroupInterfacesTemplateData(Group *group) { data_map ifaceInfo; ifaceInfo["name"] = make_data(getOutputName(iface)); - ifaceInfo["id"] = data_ptr(iface->getUniqueId()); + ifaceInfo["id"] = iface->getUniqueId(); setTemplateComments(iface, ifaceInfo); diff --git a/erpcgen/src/PythonGenerator.cpp b/erpcgen/src/PythonGenerator.cpp index 0fe7c420..a411f789 100644 --- a/erpcgen/src/PythonGenerator.cpp +++ b/erpcgen/src/PythonGenerator.cpp @@ -13,6 +13,7 @@ #include "ParseErrors.h" #include "annotations.h" #include "format_string.h" +#include "md5.h" #include #include @@ -175,7 +176,7 @@ data_map PythonGenerator::getFunctionTemplateData(Group *group, Function *fn) info["name"] = getOutputName(fn); info["prototype"] = proto; - info["id"] = fn->getUniqueId(); + info["id"] = md5(proto); info["isOneway"] = fn->isOneway(); info["isReturnValue"] = !fn->isOneway(); setTemplateComments(fn, info); diff --git a/erpcgen/src/md5.cpp b/erpcgen/src/md5.cpp new file mode 100644 index 00000000..aff9645b --- /dev/null +++ b/erpcgen/src/md5.cpp @@ -0,0 +1,362 @@ +/* MD5 + converted to C++ class by Frank Thilo (thilo@unix-ag.org) + for bzflag (http://www.bzflag.org) + + based on: + + md5.h and md5.c + reference implemantion of RFC 1321 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + +/* interface header */ +#include "md5.h" + +/* system implementation headers */ +#include + + +// Constants for MD5Transform routine. +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +/////////////////////////////////////////////// + +// F, G, H and I are basic MD5 functions. +inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) { + return x&y | ~x&z; +} + +inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) { + return x&z | y&~z; +} + +inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) { + return x^y^z; +} + +inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) { + return y ^ (x | ~z); +} + +// rotate_left rotates x left n bits. +inline MD5::uint4 MD5::rotate_left(uint4 x, int n) { + return (x << n) | (x >> (32-n)); +} + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. +inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a+ F(b,c,d) + x + ac, s) + b; +} + +inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + G(b,c,d) + x + ac, s) + b; +} + +inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + H(b,c,d) + x + ac, s) + b; +} + +inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + I(b,c,d) + x + ac, s) + b; +} + +////////////////////////////////////////////// + +// default ctor, just initailize +MD5::MD5() +{ + init(); +} + +////////////////////////////////////////////// + +// nifty shortcut ctor, compute MD5 for string and finalize it right away +MD5::MD5(const std::string &text) +{ + init(); + update(text.c_str(), text.length()); + finalize(); +} + +////////////////////////////// + +void MD5::init() +{ + finalized=false; + + count[0] = 0; + count[1] = 0; + + // load magic initialization constants. + state[0] = 0x67452301; + state[1] = 0xefcdab89; + state[2] = 0x98badcfe; + state[3] = 0x10325476; +} + +////////////////////////////// + +// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4. +void MD5::decode(uint4 output[], const uint1 input[], size_type len) +{ + for (unsigned int i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); +} + +////////////////////////////// + +// encodes input (uint4) into output (unsigned char). Assumes len is +// a multiple of 4. +void MD5::encode(uint1 output[], const uint4 input[], size_type len) +{ + for (size_type i = 0, j = 0; j < len; i++, j += 4) { + output[j] = input[i] & 0xff; + output[j+1] = (input[i] >> 8) & 0xff; + output[j+2] = (input[i] >> 16) & 0xff; + output[j+3] = (input[i] >> 24) & 0xff; + } +} + +////////////////////////////// + +// apply MD5 algo on a block +void MD5::transform(const uint1 block[blocksize]) +{ + uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + decode (x, block, blocksize); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + // Zeroize sensitive information. + memset(x, 0, sizeof x); +} + +////////////////////////////// + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block +void MD5::update(const unsigned char input[], size_type length) +{ + // compute number of bytes mod 64 + size_type index = count[0] / 8 % blocksize; + + // Update number of bits + if ((count[0] += (length << 3)) < (length << 3)) + count[1]++; + count[1] += (length >> 29); + + // number of bytes we need to fill in buffer + size_type firstpart = 64 - index; + + size_type i; + + // transform as many times as possible. + if (length >= firstpart) + { + // fill buffer first, transform + memcpy(&buffer[index], input, firstpart); + transform(buffer); + + // transform chunks of blocksize (64 bytes) + for (i = firstpart; i + blocksize <= length; i += blocksize) + transform(&input[i]); + + index = 0; + } + else + i = 0; + + // buffer remaining input + memcpy(&buffer[index], &input[i], length-i); +} + +////////////////////////////// + +// for convenience provide a verson with signed char +void MD5::update(const char input[], size_type length) +{ + update((const unsigned char*)input, length); +} + +////////////////////////////// + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. +MD5& MD5::finalize() +{ + static unsigned char padding[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (!finalized) { + // Save number of bits + unsigned char bits[8]; + encode(bits, count, 8); + + // pad out to 56 mod 64. + size_type index = count[0] / 8 % 64; + size_type padLen = (index < 56) ? (56 - index) : (120 - index); + update(padding, padLen); + + // Append length (before padding) + update(bits, 8); + + // Store state in digest + encode(digest, state, 16); + + // Zeroize sensitive information. + memset(buffer, 0, sizeof buffer); + memset(count, 0, sizeof count); + + finalized=true; + } + + return *this; +} + +////////////////////////////// + +// return hex representation of digest as string +std::string MD5::hexdigest() const +{ + if (!finalized) + return ""; + + char buf[33]; + for (int i=0; i<16; i++) + sprintf(buf+i*2, "%02x", digest[i]); + buf[32]=0; + + return std::string(buf); +} + +////////////////////////////// + +std::ostream& operator<<(std::ostream& out, MD5 md5) +{ + return out << md5.hexdigest(); +} + +////////////////////////////// + +std::string md5(const std::string str) +{ + MD5 md5 = MD5(str); + + return md5.hexdigest(); +} \ No newline at end of file diff --git a/erpcgen/src/md5.h b/erpcgen/src/md5.h new file mode 100644 index 00000000..443895db --- /dev/null +++ b/erpcgen/src/md5.h @@ -0,0 +1,93 @@ +/* MD5 + converted to C++ class by Frank Thilo (thilo@unix-ag.org) + for bzflag (http://www.bzflag.org) + + based on: + + md5.h and md5.c + reference implementation of RFC 1321 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + +#ifndef BZF_MD5_H +#define BZF_MD5_H + +#include +#include + + +// a small class for calculating MD5 hashes of strings or byte arrays +// it is not meant to be fast or secure +// +// usage: 1) feed it blocks of uchars with update() +// 2) finalize() +// 3) get hexdigest() string +// or +// MD5(std::string).hexdigest() +// +// assumes that char is 8 bit and int is 32 bit +class MD5 +{ +public: + typedef unsigned int size_type; // must be 32bit + + MD5(); + MD5(const std::string& text); + void update(const unsigned char *buf, size_type length); + void update(const char *buf, size_type length); + MD5& finalize(); + std::string hexdigest() const; + friend std::ostream& operator<<(std::ostream&, MD5 md5); + +private: + void init(); + typedef unsigned char uint1; // 8bit + typedef unsigned int uint4; // 32bit + enum {blocksize = 64}; // VC6 won't eat a const static int here + + void transform(const uint1 block[blocksize]); + static void decode(uint4 output[], const uint1 input[], size_type len); + static void encode(uint1 output[], const uint4 input[], size_type len); + + bool finalized; + uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk + uint4 count[2]; // 64bit counter for number of bits (lo, hi) + uint4 state[4]; // digest so far + uint1 digest[16]; // the result + + // low level logic operations + static inline uint4 F(uint4 x, uint4 y, uint4 z); + static inline uint4 G(uint4 x, uint4 y, uint4 z); + static inline uint4 H(uint4 x, uint4 y, uint4 z); + static inline uint4 I(uint4 x, uint4 y, uint4 z); + static inline uint4 rotate_left(uint4 x, int n); + static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); +}; + +std::string md5(const std::string str); + +#endif \ No newline at end of file diff --git a/erpcgen/src/templates/c_common_header.template b/erpcgen/src/templates/c_common_header.template index 77b0c9a6..e59f45dc 100644 --- a/erpcgen/src/templates/c_common_header.template +++ b/erpcgen/src/templates/c_common_header.template @@ -108,15 +108,12 @@ extern const {$c.typeAndName};{$c.ilComment}{$loop.addNewLineIfNotLast} {% if not genCommonTypesFile %} {% for iface in group.interfaces %} /*! @brief {$iface.name} identifiers */ -enum _{$iface.name}_ids -{ - k{$iface.name}_service_id = {$iface.id}, +constexpr uint8_t k{$iface.name}_service_id = {$iface.id}; {% for fn in iface.functions %} - k{$iface.name}_{$fn.name}_id = {$fn.id}, +constexpr const char* k{$iface.name}_{$fn.name}_id = "{$fn.id}"; {% endfor %} -}; - {% endfor %} + #if defined(__cplusplus) extern "C" { #endif diff --git a/erpcgen/src/templates/c_server_header.template b/erpcgen/src/templates/c_server_header.template index 68ed101d..56bb5007 100644 --- a/erpcgen/src/templates/c_server_header.template +++ b/erpcgen/src/templates/c_server_header.template @@ -30,7 +30,7 @@ public: {$iface.serviceClassName}() : Service(k{$iface.name}_service_id) {} /*! @brief Call the correct server shim based on method unique ID. */ - virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory); + virtual erpc_status_t handleInvocation(erpc::Md5Hash methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory); private: {% for fn in iface.functions %} diff --git a/erpcgen/src/templates/c_server_source.template b/erpcgen/src/templates/c_server_source.template index 5195b6c1..6059099f 100644 --- a/erpcgen/src/templates/c_server_source.template +++ b/erpcgen/src/templates/c_server_source.template @@ -19,6 +19,8 @@ extern "C" } {% endif -- empty(group.includes) %} +#include + {$checkVersion()} {$>checkCrc()} using namespace erpc; @@ -204,30 +206,18 @@ static erpc_status_t {$callbackType.name}_shim(uint32_t serviceID, uint32_t func {% for iface in group.interfaces -- service subclass method impl %} // Call the correct server shim based on method unique ID. -erpc_status_t {$iface.serviceClassName}::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory) +erpc_status_t {$iface.serviceClassName}::handleInvocation(erpc::Md5Hash methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory) { - erpc_status_t erpcStatus; + string hash(methodId); {% if codecClass != "Codec" %} {$codecClass} *_codec = static_cast<{$codecClass} *>(codec); {% endif %} - switch (methodId) - { {% for fn in iface.functions %} - case k{$iface.name}_{$fn.name}_id: - { - erpcStatus = {$fn.name}_shim({%if codecClass == "Codec"%}codec{% else %}_codec{% endif %}, messageFactory, sequence); - break; - } - -{% endfor -- fn %} - default: - { - erpcStatus = kErpcStatus_InvalidArgument; - break; - } + if(hash.compare(k{$iface.name}_{$fn.name}_id) == 0){ + return {$fn.name}_shim({%if codecClass == "Codec"%}codec{% else %}_codec{% endif %}, messageFactory, sequence); } - - return erpcStatus; +{% endfor -- fn %} + return kErpcStatus_InvalidArgument; } {% for fn in iface.functions %} From 95b6db72568cf9b37e793007d06c49df6e8cdb94 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Sun, 3 Oct 2021 15:40:47 +0200 Subject: [PATCH 2/4] changed method / request id of rpc functions to be md5 hash instead of uint32_t --- Makefile | 2 +- erpc_c/infra/erpc_basic_codec.cpp | 28 +- erpc_c/infra/erpc_basic_codec.h | 4 +- erpc_c/infra/erpc_client_manager.cpp | 6 +- erpc_c/infra/erpc_client_manager.h | 4 +- erpc_c/infra/erpc_codec.h | 18 +- erpc_c/infra/erpc_server.cpp | 8 +- erpc_c/infra/erpc_server.h | 6 +- erpc_c/infra/erpc_simple_server.cpp | 6 +- erpc_c/infra/erpc_simple_server.h | 4 +- erpc_c/infra/erpc_transport_arbitrator.cpp | 4 +- erpc_c/port/erpc_threading_pthreads.cpp | 6 +- erpcgen/Makefile | 1 + erpcgen/src/CGenerator.cpp | 4 +- erpcgen/src/Generator.cpp | 2 +- erpcgen/src/PythonGenerator.cpp | 3 +- erpcgen/src/md5.cpp | 362 ++++++++++++++++++ erpcgen/src/md5.h | 93 +++++ .../src/templates/c_common_header.template | 9 +- .../src/templates/c_server_header.template | 2 +- .../src/templates/c_server_source.template | 26 +- 21 files changed, 532 insertions(+), 66 deletions(-) create mode 100644 erpcgen/src/md5.cpp create mode 100644 erpcgen/src/md5.h diff --git a/Makefile b/Makefile index 5dca3bf6..cc947963 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ include mk/erpc_common.mk #.NOTPARALLEL: ifeq "$(is_linux)" "1" -ERPCSNIFFER = erpcsniffer +#ERPCSNIFFER = erpcsniffer endif # Subdirectories to run make on. diff --git a/erpc_c/infra/erpc_basic_codec.cpp b/erpc_c/infra/erpc_basic_codec.cpp index 38c2c521..132d3d26 100644 --- a/erpc_c/infra/erpc_basic_codec.cpp +++ b/erpc_c/infra/erpc_basic_codec.cpp @@ -19,18 +19,22 @@ using namespace erpc; + //////////////////////////////////////////////////////////////////////////////// // Code //////////////////////////////////////////////////////////////////////////////// const uint8_t BasicCodec::kBasicCodecVersion = 1; -void BasicCodec::startWriteMessage(message_type_t type, uint32_t service, uint32_t request, uint32_t sequence) +void BasicCodec::startWriteMessage(message_type_t type, uint32_t service, const Md5Hash request, uint32_t sequence) { - uint32_t header = (kBasicCodecVersion << 24) | ((service & 0xff) << 16) | ((request & 0xff) << 8) | (type & 0xff); - - write(header); + Header header(kBasicCodecVersion, + static_cast((service & 0xff)), + request, + type + ); + writeData(&header, sizeof(Header)); write(sequence); } @@ -178,25 +182,25 @@ void BasicCodec::writeCallback(funPtr callback1, funPtr callback2) } } -void BasicCodec::startReadMessage(message_type_t *type, uint32_t *service, uint32_t *request, uint32_t *sequence) +void BasicCodec::startReadMessage(message_type_t *type, uint32_t *service, Md5Hash request, uint32_t *sequence) { - uint32_t header; + Header header; + readData(&header, sizeof(Header)); - read(&header); - - if (((header >> 24) & 0xffU) != kBasicCodecVersion) + if (header.codecVersion != kBasicCodecVersion) { updateStatus(kErpcStatus_InvalidMessageVersion); } if (!m_status) { - *service = ((header >> 16) & 0xffU); - *request = ((header >> 8) & 0xffU); - *type = static_cast(header & 0xffU); + *service = header.service; + std::memcpy(request, header.id, sizeof(Md5Hash)); + *type = static_cast(header.type); read(sequence); } + } void BasicCodec::readData(void *value, uint32_t length) diff --git a/erpc_c/infra/erpc_basic_codec.h b/erpc_c/infra/erpc_basic_codec.h index 8fb44d0d..c5ef288b 100644 --- a/erpc_c/infra/erpc_basic_codec.h +++ b/erpc_c/infra/erpc_basic_codec.h @@ -59,7 +59,7 @@ class BasicCodec : public Codec * @param[in] sequence Send sequence number to be sure that * received message is reply for current request. or write function. */ - virtual void startWriteMessage(message_type_t type, uint32_t service, uint32_t request, uint32_t sequence) override; + virtual void startWriteMessage(message_type_t type, uint32_t service, const Md5Hash request, uint32_t sequence) override; /*! * @brief Prototype for write data stream. @@ -219,7 +219,7 @@ class BasicCodec : public Codec * @param[out] sequence Returned sequence number to be sure that * received message is reply for current request. */ - virtual void startReadMessage(message_type_t *type, uint32_t *service, uint32_t *request, + virtual void startReadMessage(message_type_t *type, uint32_t *service, Md5Hash request, uint32_t *sequence) override; /*! diff --git a/erpc_c/infra/erpc_client_manager.cpp b/erpc_c/infra/erpc_client_manager.cpp index 65e162ca..ef4eb2d6 100644 --- a/erpc_c/infra/erpc_client_manager.cpp +++ b/erpc_c/infra/erpc_client_manager.cpp @@ -169,7 +169,7 @@ void ClientManager::verifyReply(RequestContext &request) { message_type_t msgType; uint32_t service; - uint32_t requestNumber; + Md5Hash requestNumber; uint32_t sequence; // Some transport layers change the request's message buffer pointer (for things like zero @@ -177,7 +177,7 @@ void ClientManager::verifyReply(RequestContext &request) request.getCodec()->reset(); // Extract the reply header. - request.getCodec()->startReadMessage(&msgType, &service, &requestNumber, &sequence); + request.getCodec()->startReadMessage(&msgType, &service, requestNumber, &sequence); if (request.getCodec()->isStatusOk() == true) { @@ -218,7 +218,7 @@ void ClientManager::releaseRequest(RequestContext &request) m_codecFactory->dispose(request.getCodec()); } -void ClientManager::callErrorHandler(erpc_status_t err, uint32_t functionID) +void ClientManager::callErrorHandler(erpc_status_t err, const Md5Hash functionID) { if (m_errorHandler != NULL) { diff --git a/erpc_c/infra/erpc_client_manager.h b/erpc_c/infra/erpc_client_manager.h index c779db36..0007d019 100644 --- a/erpc_c/infra/erpc_client_manager.h +++ b/erpc_c/infra/erpc_client_manager.h @@ -30,7 +30,7 @@ extern "C" { #endif typedef void (*client_error_handler_t)(erpc_status_t err, - uint32_t functionID); /*!< eRPC error handler function type. */ + const Md5Hash functionID); /*!< eRPC error handler function type. */ #ifdef __cplusplus } @@ -136,7 +136,7 @@ class ClientManager : public ClientServerCommon * @param[in] err Specify function status at the end of eRPC call. * @param[in] functionID Specify eRPC function call. */ - void callErrorHandler(erpc_status_t err, uint32_t functionID); + void callErrorHandler(erpc_status_t err, const Md5Hash functionID); #if ERPC_NESTED_CALLS /*! diff --git a/erpc_c/infra/erpc_codec.h b/erpc_c/infra/erpc_codec.h index f5861f31..b87ddb03 100644 --- a/erpc_c/infra/erpc_codec.h +++ b/erpc_c/infra/erpc_codec.h @@ -43,6 +43,20 @@ typedef enum _message_type typedef void *funPtr; // Pointer to functions typedef funPtr *arrayOfFunPtr; // Pointer to array of functions +using Md5Hash = char[33]; + +struct Header{ + const uint8_t codecVersion = 0; + uint8_t service = 0; + char id[32]; + uint8_t type = 0; + Header(){} + Header(const uint8_t version, uint8_t service, const Md5Hash hash, message_type_t type) : codecVersion(version), service(service), type(static_cast(type & 0xff)){ + std::memcpy(id, hash, sizeof(Md5Hash)-1); + } +}; + + /*! * @brief Abstract serialization encoder/decoder interface. * @@ -135,7 +149,7 @@ class Codec * @param[in] sequence Send sequence number to be sure that * received message is reply for current request. */ - virtual void startWriteMessage(message_type_t type, uint32_t service, uint32_t request, uint32_t sequence) = 0; + virtual void startWriteMessage(message_type_t type, uint32_t service, const Md5Hash request, uint32_t sequence) = 0; /*! * @brief Prototype for write boolean value. @@ -287,7 +301,7 @@ class Codec * @param[in] sequence Returned sequence number to be sure that * received message is reply for current request. */ - virtual void startReadMessage(message_type_t *type, uint32_t *service, uint32_t *request, uint32_t *sequence) = 0; + virtual void startReadMessage(message_type_t *type, uint32_t *service, Md5Hash request, uint32_t *sequence) = 0; /*! * @brief Prototype for read boolean value. diff --git a/erpc_c/infra/erpc_server.cpp b/erpc_c/infra/erpc_server.cpp index 4c9c0fec..593c559c 100644 --- a/erpc_c/infra/erpc_server.cpp +++ b/erpc_c/infra/erpc_server.cpp @@ -69,14 +69,14 @@ void Server::removeService(Service *service) } } -erpc_status_t Server::readHeadOfMessage(Codec *codec, message_type_t &msgType, uint32_t &serviceId, uint32_t &methodId, - uint32_t &sequence) +erpc_status_t Server::readHeadOfMessage(Codec *codec, message_type_t &msgType, uint32_t &serviceId, Md5Hash methodId, + uint32_t& sequence) { - codec->startReadMessage(&msgType, &serviceId, &methodId, &sequence); + codec->startReadMessage(&msgType, &serviceId, methodId, &sequence); return codec->getStatus(); } -erpc_status_t Server::processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, +erpc_status_t Server::processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence) { erpc_status_t err = kErpcStatus_Success; diff --git a/erpc_c/infra/erpc_server.h b/erpc_c/infra/erpc_server.h index 4bc2003a..5e6f07e2 100644 --- a/erpc_c/infra/erpc_server.h +++ b/erpc_c/infra/erpc_server.h @@ -87,7 +87,7 @@ class Service * * @return Based on handleInvocation implementation. */ - virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, Codec *codec, + virtual erpc_status_t handleInvocation(Md5Hash methodId, uint32_t sequence, Codec *codec, MessageBufferFactory *messageFactory) = 0; protected: @@ -186,7 +186,7 @@ class Server : public ClientServerCommon * * @returns #kErpcStatus_Success or based on codec startReadMessage. */ - virtual erpc_status_t processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, + virtual erpc_status_t processMessage(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence); /*! @@ -201,7 +201,7 @@ class Server : public ClientServerCommon * @returns #kErpcStatus_Success or based on service handleInvocation. */ virtual erpc_status_t readHeadOfMessage(Codec *codec, message_type_t &msgType, uint32_t &serviceId, - uint32_t &methodId, uint32_t &sequence); + Md5Hash methodId, uint32_t &sequence); /*! * @brief This function finds service base on service ID. diff --git a/erpc_c/infra/erpc_simple_server.cpp b/erpc_c/infra/erpc_simple_server.cpp index 39f43a2d..691fcd96 100644 --- a/erpc_c/infra/erpc_simple_server.cpp +++ b/erpc_c/infra/erpc_simple_server.cpp @@ -36,7 +36,7 @@ erpc_status_t SimpleServer::runInternal(void) // Handle the request. message_type_t msgType; uint32_t serviceId; - uint32_t methodId; + Md5Hash methodId; uint32_t sequence; erpc_status_t err = runInternalBegin(&codec, buff, msgType, serviceId, methodId, sequence); @@ -49,7 +49,7 @@ erpc_status_t SimpleServer::runInternal(void) } erpc_status_t SimpleServer::runInternalBegin(Codec **codec, MessageBuffer &buff, message_type_t &msgType, - uint32_t &serviceId, uint32_t &methodId, uint32_t &sequence) + uint32_t &serviceId, Md5Hash methodId, uint32_t &sequence) { erpc_status_t err = kErpcStatus_Success; @@ -116,7 +116,7 @@ erpc_status_t SimpleServer::runInternalBegin(Codec **codec, MessageBuffer &buff, return err; } -erpc_status_t SimpleServer::runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, +erpc_status_t SimpleServer::runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence) { erpc_status_t err = processMessage(codec, msgType, serviceId, methodId, sequence); diff --git a/erpc_c/infra/erpc_simple_server.h b/erpc_c/infra/erpc_simple_server.h index 651f7270..761a8190 100644 --- a/erpc_c/infra/erpc_simple_server.h +++ b/erpc_c/infra/erpc_simple_server.h @@ -79,7 +79,7 @@ class SimpleServer : public Server * @returns #kErpcStatus_Success or based on service handleInvocation. */ erpc_status_t runInternalBegin(Codec **codec, MessageBuffer &buff, message_type_t &msgType, uint32_t &serviceId, - uint32_t &methodId, uint32_t &sequence); + Md5Hash methodId, uint32_t &sequence); /*! * @brief This function process message and handle sending respond. @@ -92,7 +92,7 @@ class SimpleServer : public Server * * @returns #kErpcStatus_Success or based on service handleInvocation. */ - erpc_status_t runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, uint32_t methodId, + erpc_status_t runInternalEnd(Codec *codec, message_type_t msgType, uint32_t serviceId, Md5Hash methodId, uint32_t sequence); #if ERPC_NESTED_CALLS diff --git a/erpc_c/infra/erpc_transport_arbitrator.cpp b/erpc_c/infra/erpc_transport_arbitrator.cpp index 23f096cf..b69671f5 100644 --- a/erpc_c/infra/erpc_transport_arbitrator.cpp +++ b/erpc_c/infra/erpc_transport_arbitrator.cpp @@ -66,7 +66,7 @@ erpc_status_t TransportArbitrator::receive(MessageBuffer *message) erpc_status_t err; message_type_t msgType; uint32_t service; - uint32_t requestNumber; + Md5Hash requestNumber; uint32_t sequence; PendingClientInfo *client; @@ -94,7 +94,7 @@ erpc_status_t TransportArbitrator::receive(MessageBuffer *message) m_codec->setBuffer(*message); // Parse the message header. - m_codec->startReadMessage(&msgType, &service, &requestNumber, &sequence); + m_codec->startReadMessage(&msgType, &service, requestNumber, &sequence); err = m_codec->getStatus(); if (err != kErpcStatus_Success) { diff --git a/erpc_c/port/erpc_threading_pthreads.cpp b/erpc_c/port/erpc_threading_pthreads.cpp index 3586013c..5107caea 100644 --- a/erpc_c/port/erpc_threading_pthreads.cpp +++ b/erpc_c/port/erpc_threading_pthreads.cpp @@ -44,23 +44,25 @@ Thread::Thread(const char *name) { } -Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name) +Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name, thread_stack_pointer ptr) : m_name(name) , m_entry(entry) , m_arg(0) , m_stackSize(stackSize) , m_priority(priority) , m_thread(0) +,m_stackPtr(ptr) { } Thread::~Thread(void) {} -void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize) +void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize, thread_stack_pointer ptr) { m_entry = entry; m_stackSize = stackSize; m_priority = priority; + m_stackPtr = ptr; } void Thread::start(void *arg) diff --git a/erpcgen/Makefile b/erpcgen/Makefile index 744736a6..db2c874e 100644 --- a/erpcgen/Makefile +++ b/erpcgen/Makefile @@ -58,6 +58,7 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \ $(ERPC_ROOT)/erpcgen/src/UniqueIdChecker.cpp \ $(ERPC_ROOT)/erpcgen/src/CGenerator.cpp \ $(ERPC_ROOT)/erpcgen/src/PythonGenerator.cpp \ + $(ERPC_ROOT)/erpcgen/src/md5.cpp \ $(ERPC_ROOT)/erpcgen/src/erpcgen.cpp \ $(ERPC_ROOT)/erpcgen/src/ErpcLexer.cpp \ $(ERPC_ROOT)/erpcgen/src/Generator.cpp \ diff --git a/erpcgen/src/CGenerator.cpp b/erpcgen/src/CGenerator.cpp index 6b732e45..6ade6baa 100644 --- a/erpcgen/src/CGenerator.cpp +++ b/erpcgen/src/CGenerator.cpp @@ -13,11 +13,13 @@ #include "ParseErrors.h" #include "annotations.h" #include "format_string.h" +#include "md5.h" #include #include #include + using namespace erpcgen; using namespace cpptempl; using namespace std; @@ -1692,7 +1694,7 @@ data_map CGenerator::getFunctionTemplateData(Group *group, Function *fn) string proto = getFunctionPrototype(group, fn); info["prototype"] = proto; info["name"] = getOutputName(fn); - info["id"] = fn->getUniqueId(); + info["id"] = md5(proto); return info; } diff --git a/erpcgen/src/Generator.cpp b/erpcgen/src/Generator.cpp index cfd4c538..08ac4c75 100644 --- a/erpcgen/src/Generator.cpp +++ b/erpcgen/src/Generator.cpp @@ -406,7 +406,7 @@ data_list Generator::makeGroupInterfacesTemplateData(Group *group) { data_map ifaceInfo; ifaceInfo["name"] = make_data(getOutputName(iface)); - ifaceInfo["id"] = data_ptr(iface->getUniqueId()); + ifaceInfo["id"] = iface->getUniqueId(); setTemplateComments(iface, ifaceInfo); diff --git a/erpcgen/src/PythonGenerator.cpp b/erpcgen/src/PythonGenerator.cpp index 0fe7c420..a411f789 100644 --- a/erpcgen/src/PythonGenerator.cpp +++ b/erpcgen/src/PythonGenerator.cpp @@ -13,6 +13,7 @@ #include "ParseErrors.h" #include "annotations.h" #include "format_string.h" +#include "md5.h" #include #include @@ -175,7 +176,7 @@ data_map PythonGenerator::getFunctionTemplateData(Group *group, Function *fn) info["name"] = getOutputName(fn); info["prototype"] = proto; - info["id"] = fn->getUniqueId(); + info["id"] = md5(proto); info["isOneway"] = fn->isOneway(); info["isReturnValue"] = !fn->isOneway(); setTemplateComments(fn, info); diff --git a/erpcgen/src/md5.cpp b/erpcgen/src/md5.cpp new file mode 100644 index 00000000..aff9645b --- /dev/null +++ b/erpcgen/src/md5.cpp @@ -0,0 +1,362 @@ +/* MD5 + converted to C++ class by Frank Thilo (thilo@unix-ag.org) + for bzflag (http://www.bzflag.org) + + based on: + + md5.h and md5.c + reference implemantion of RFC 1321 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + +/* interface header */ +#include "md5.h" + +/* system implementation headers */ +#include + + +// Constants for MD5Transform routine. +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +/////////////////////////////////////////////// + +// F, G, H and I are basic MD5 functions. +inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) { + return x&y | ~x&z; +} + +inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) { + return x&z | y&~z; +} + +inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) { + return x^y^z; +} + +inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) { + return y ^ (x | ~z); +} + +// rotate_left rotates x left n bits. +inline MD5::uint4 MD5::rotate_left(uint4 x, int n) { + return (x << n) | (x >> (32-n)); +} + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. +inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a+ F(b,c,d) + x + ac, s) + b; +} + +inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + G(b,c,d) + x + ac, s) + b; +} + +inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + H(b,c,d) + x + ac, s) + b; +} + +inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + I(b,c,d) + x + ac, s) + b; +} + +////////////////////////////////////////////// + +// default ctor, just initailize +MD5::MD5() +{ + init(); +} + +////////////////////////////////////////////// + +// nifty shortcut ctor, compute MD5 for string and finalize it right away +MD5::MD5(const std::string &text) +{ + init(); + update(text.c_str(), text.length()); + finalize(); +} + +////////////////////////////// + +void MD5::init() +{ + finalized=false; + + count[0] = 0; + count[1] = 0; + + // load magic initialization constants. + state[0] = 0x67452301; + state[1] = 0xefcdab89; + state[2] = 0x98badcfe; + state[3] = 0x10325476; +} + +////////////////////////////// + +// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4. +void MD5::decode(uint4 output[], const uint1 input[], size_type len) +{ + for (unsigned int i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); +} + +////////////////////////////// + +// encodes input (uint4) into output (unsigned char). Assumes len is +// a multiple of 4. +void MD5::encode(uint1 output[], const uint4 input[], size_type len) +{ + for (size_type i = 0, j = 0; j < len; i++, j += 4) { + output[j] = input[i] & 0xff; + output[j+1] = (input[i] >> 8) & 0xff; + output[j+2] = (input[i] >> 16) & 0xff; + output[j+3] = (input[i] >> 24) & 0xff; + } +} + +////////////////////////////// + +// apply MD5 algo on a block +void MD5::transform(const uint1 block[blocksize]) +{ + uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + decode (x, block, blocksize); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + // Zeroize sensitive information. + memset(x, 0, sizeof x); +} + +////////////////////////////// + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block +void MD5::update(const unsigned char input[], size_type length) +{ + // compute number of bytes mod 64 + size_type index = count[0] / 8 % blocksize; + + // Update number of bits + if ((count[0] += (length << 3)) < (length << 3)) + count[1]++; + count[1] += (length >> 29); + + // number of bytes we need to fill in buffer + size_type firstpart = 64 - index; + + size_type i; + + // transform as many times as possible. + if (length >= firstpart) + { + // fill buffer first, transform + memcpy(&buffer[index], input, firstpart); + transform(buffer); + + // transform chunks of blocksize (64 bytes) + for (i = firstpart; i + blocksize <= length; i += blocksize) + transform(&input[i]); + + index = 0; + } + else + i = 0; + + // buffer remaining input + memcpy(&buffer[index], &input[i], length-i); +} + +////////////////////////////// + +// for convenience provide a verson with signed char +void MD5::update(const char input[], size_type length) +{ + update((const unsigned char*)input, length); +} + +////////////////////////////// + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. +MD5& MD5::finalize() +{ + static unsigned char padding[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (!finalized) { + // Save number of bits + unsigned char bits[8]; + encode(bits, count, 8); + + // pad out to 56 mod 64. + size_type index = count[0] / 8 % 64; + size_type padLen = (index < 56) ? (56 - index) : (120 - index); + update(padding, padLen); + + // Append length (before padding) + update(bits, 8); + + // Store state in digest + encode(digest, state, 16); + + // Zeroize sensitive information. + memset(buffer, 0, sizeof buffer); + memset(count, 0, sizeof count); + + finalized=true; + } + + return *this; +} + +////////////////////////////// + +// return hex representation of digest as string +std::string MD5::hexdigest() const +{ + if (!finalized) + return ""; + + char buf[33]; + for (int i=0; i<16; i++) + sprintf(buf+i*2, "%02x", digest[i]); + buf[32]=0; + + return std::string(buf); +} + +////////////////////////////// + +std::ostream& operator<<(std::ostream& out, MD5 md5) +{ + return out << md5.hexdigest(); +} + +////////////////////////////// + +std::string md5(const std::string str) +{ + MD5 md5 = MD5(str); + + return md5.hexdigest(); +} \ No newline at end of file diff --git a/erpcgen/src/md5.h b/erpcgen/src/md5.h new file mode 100644 index 00000000..443895db --- /dev/null +++ b/erpcgen/src/md5.h @@ -0,0 +1,93 @@ +/* MD5 + converted to C++ class by Frank Thilo (thilo@unix-ag.org) + for bzflag (http://www.bzflag.org) + + based on: + + md5.h and md5.c + reference implementation of RFC 1321 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + +#ifndef BZF_MD5_H +#define BZF_MD5_H + +#include +#include + + +// a small class for calculating MD5 hashes of strings or byte arrays +// it is not meant to be fast or secure +// +// usage: 1) feed it blocks of uchars with update() +// 2) finalize() +// 3) get hexdigest() string +// or +// MD5(std::string).hexdigest() +// +// assumes that char is 8 bit and int is 32 bit +class MD5 +{ +public: + typedef unsigned int size_type; // must be 32bit + + MD5(); + MD5(const std::string& text); + void update(const unsigned char *buf, size_type length); + void update(const char *buf, size_type length); + MD5& finalize(); + std::string hexdigest() const; + friend std::ostream& operator<<(std::ostream&, MD5 md5); + +private: + void init(); + typedef unsigned char uint1; // 8bit + typedef unsigned int uint4; // 32bit + enum {blocksize = 64}; // VC6 won't eat a const static int here + + void transform(const uint1 block[blocksize]); + static void decode(uint4 output[], const uint1 input[], size_type len); + static void encode(uint1 output[], const uint4 input[], size_type len); + + bool finalized; + uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk + uint4 count[2]; // 64bit counter for number of bits (lo, hi) + uint4 state[4]; // digest so far + uint1 digest[16]; // the result + + // low level logic operations + static inline uint4 F(uint4 x, uint4 y, uint4 z); + static inline uint4 G(uint4 x, uint4 y, uint4 z); + static inline uint4 H(uint4 x, uint4 y, uint4 z); + static inline uint4 I(uint4 x, uint4 y, uint4 z); + static inline uint4 rotate_left(uint4 x, int n); + static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); +}; + +std::string md5(const std::string str); + +#endif \ No newline at end of file diff --git a/erpcgen/src/templates/c_common_header.template b/erpcgen/src/templates/c_common_header.template index 77b0c9a6..e59f45dc 100644 --- a/erpcgen/src/templates/c_common_header.template +++ b/erpcgen/src/templates/c_common_header.template @@ -108,15 +108,12 @@ extern const {$c.typeAndName};{$c.ilComment}{$loop.addNewLineIfNotLast} {% if not genCommonTypesFile %} {% for iface in group.interfaces %} /*! @brief {$iface.name} identifiers */ -enum _{$iface.name}_ids -{ - k{$iface.name}_service_id = {$iface.id}, +constexpr uint8_t k{$iface.name}_service_id = {$iface.id}; {% for fn in iface.functions %} - k{$iface.name}_{$fn.name}_id = {$fn.id}, +constexpr const char* k{$iface.name}_{$fn.name}_id = "{$fn.id}"; {% endfor %} -}; - {% endfor %} + #if defined(__cplusplus) extern "C" { #endif diff --git a/erpcgen/src/templates/c_server_header.template b/erpcgen/src/templates/c_server_header.template index 68ed101d..56bb5007 100644 --- a/erpcgen/src/templates/c_server_header.template +++ b/erpcgen/src/templates/c_server_header.template @@ -30,7 +30,7 @@ public: {$iface.serviceClassName}() : Service(k{$iface.name}_service_id) {} /*! @brief Call the correct server shim based on method unique ID. */ - virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory); + virtual erpc_status_t handleInvocation(erpc::Md5Hash methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory); private: {% for fn in iface.functions %} diff --git a/erpcgen/src/templates/c_server_source.template b/erpcgen/src/templates/c_server_source.template index 5195b6c1..6059099f 100644 --- a/erpcgen/src/templates/c_server_source.template +++ b/erpcgen/src/templates/c_server_source.template @@ -19,6 +19,8 @@ extern "C" } {% endif -- empty(group.includes) %} +#include + {$checkVersion()} {$>checkCrc()} using namespace erpc; @@ -204,30 +206,18 @@ static erpc_status_t {$callbackType.name}_shim(uint32_t serviceID, uint32_t func {% for iface in group.interfaces -- service subclass method impl %} // Call the correct server shim based on method unique ID. -erpc_status_t {$iface.serviceClassName}::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory) +erpc_status_t {$iface.serviceClassName}::handleInvocation(erpc::Md5Hash methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory) { - erpc_status_t erpcStatus; + string hash(methodId); {% if codecClass != "Codec" %} {$codecClass} *_codec = static_cast<{$codecClass} *>(codec); {% endif %} - switch (methodId) - { {% for fn in iface.functions %} - case k{$iface.name}_{$fn.name}_id: - { - erpcStatus = {$fn.name}_shim({%if codecClass == "Codec"%}codec{% else %}_codec{% endif %}, messageFactory, sequence); - break; - } - -{% endfor -- fn %} - default: - { - erpcStatus = kErpcStatus_InvalidArgument; - break; - } + if(hash.compare(k{$iface.name}_{$fn.name}_id) == 0){ + return {$fn.name}_shim({%if codecClass == "Codec"%}codec{% else %}_codec{% endif %}, messageFactory, sequence); } - - return erpcStatus; +{% endfor -- fn %} + return kErpcStatus_InvalidArgument; } {% for fn in iface.functions %} From 0d3e1c3239cdedc43d05121f157d5775621f6e88 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Thu, 7 Oct 2021 11:04:57 +0200 Subject: [PATCH 3/4] fixed error in md5 hash generation, variable names should not be part of the hash :) --- erpc_c/infra/erpc_client_manager.h | 2 +- erpcgen/src/CGenerator.cpp | 11 ++++++++--- erpcgen/src/CGenerator.h | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/erpc_c/infra/erpc_client_manager.h b/erpc_c/infra/erpc_client_manager.h index 0007d019..6affa150 100644 --- a/erpc_c/infra/erpc_client_manager.h +++ b/erpc_c/infra/erpc_client_manager.h @@ -30,7 +30,7 @@ extern "C" { #endif typedef void (*client_error_handler_t)(erpc_status_t err, - const Md5Hash functionID); /*!< eRPC error handler function type. */ + const erpc::Md5Hash functionID); /*!< eRPC error handler function type. */ #ifdef __cplusplus } diff --git a/erpcgen/src/CGenerator.cpp b/erpcgen/src/CGenerator.cpp index 6ade6baa..dc55738d 100644 --- a/erpcgen/src/CGenerator.cpp +++ b/erpcgen/src/CGenerator.cpp @@ -1694,7 +1694,9 @@ data_map CGenerator::getFunctionTemplateData(Group *group, Function *fn) string proto = getFunctionPrototype(group, fn); info["prototype"] = proto; info["name"] = getOutputName(fn); - info["id"] = md5(proto); + std::string specialProto = getFunctionPrototype(group, fn, "", true); + std::string hash = md5(specialProto); + info["id"] = hash; return info; } @@ -1945,7 +1947,7 @@ string CGenerator::getFunctionServerCall(Function *fn, FunctionType *functionTyp return proto + ");"; } -string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, std::string name) +string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, std::string name, bool skipVariableNames) { DataType *dataTypeReturn = fn->getReturnType(); string proto = getExtraPointerInReturn(dataTypeReturn); @@ -1994,7 +1996,10 @@ string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, std::str for (auto it : params) { bool isLast = (n == params.size() - 1); - string paramSignature = getOutputName(it); + string paramSignature = ""; + if(!skipVariableNames){ + paramSignature = getOutputName(it); + } DataType *dataType = it->getDataType(); DataType *trueDataType = dataType->getTrueDataType(); diff --git a/erpcgen/src/CGenerator.h b/erpcgen/src/CGenerator.h index 36c7e02a..57af17d8 100644 --- a/erpcgen/src/CGenerator.h +++ b/erpcgen/src/CGenerator.h @@ -424,7 +424,7 @@ class CGenerator : public Generator * * @return String prototype representation for given function. */ - std::string getFunctionPrototype(Group *group, FunctionBase *fn, std::string name = ""); + std::string getFunctionPrototype(Group *group, FunctionBase *fn, std::string name = "", bool skipVariableNames = false); /*! * @brief This function return interface function representation called by server side. From cc22c2fbf3d004d39c61873c4b5a60d4343be342 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Thu, 14 Oct 2021 11:25:37 +0200 Subject: [PATCH 4/4] changed name of header to payloadheader --- erpc_c/infra/erpc_basic_codec.cpp | 8 ++++---- erpc_c/infra/erpc_codec.h | 6 +++--- erpc_c/infra/erpc_framed_transport.h | 16 +++++++++------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/erpc_c/infra/erpc_basic_codec.cpp b/erpc_c/infra/erpc_basic_codec.cpp index 132d3d26..5b9af013 100644 --- a/erpc_c/infra/erpc_basic_codec.cpp +++ b/erpc_c/infra/erpc_basic_codec.cpp @@ -28,13 +28,13 @@ const uint8_t BasicCodec::kBasicCodecVersion = 1; void BasicCodec::startWriteMessage(message_type_t type, uint32_t service, const Md5Hash request, uint32_t sequence) { - Header header(kBasicCodecVersion, + PayloadHeader header(kBasicCodecVersion, static_cast((service & 0xff)), request, type ); - writeData(&header, sizeof(Header)); + writeData(&header, sizeof(PayloadHeader)); write(sequence); } @@ -184,8 +184,8 @@ void BasicCodec::writeCallback(funPtr callback1, funPtr callback2) void BasicCodec::startReadMessage(message_type_t *type, uint32_t *service, Md5Hash request, uint32_t *sequence) { - Header header; - readData(&header, sizeof(Header)); + PayloadHeader header; + readData(&header, sizeof(PayloadHeader)); if (header.codecVersion != kBasicCodecVersion) { diff --git a/erpc_c/infra/erpc_codec.h b/erpc_c/infra/erpc_codec.h index b87ddb03..fb338621 100644 --- a/erpc_c/infra/erpc_codec.h +++ b/erpc_c/infra/erpc_codec.h @@ -45,13 +45,13 @@ typedef funPtr *arrayOfFunPtr; // Pointer to array of functions using Md5Hash = char[33]; -struct Header{ +struct PayloadHeader{ const uint8_t codecVersion = 0; uint8_t service = 0; char id[32]; uint8_t type = 0; - Header(){} - Header(const uint8_t version, uint8_t service, const Md5Hash hash, message_type_t type) : codecVersion(version), service(service), type(static_cast(type & 0xff)){ + PayloadHeader(){} + PayloadHeader(const uint8_t version, uint8_t service, const Md5Hash hash, message_type_t type) : codecVersion(version), service(service), type(static_cast(type & 0xff)){ std::memcpy(id, hash, sizeof(Md5Hash)-1); } }; diff --git a/erpc_c/infra/erpc_framed_transport.h b/erpc_c/infra/erpc_framed_transport.h index da51ddb3..cbfc7330 100644 --- a/erpc_c/infra/erpc_framed_transport.h +++ b/erpc_c/infra/erpc_framed_transport.h @@ -33,6 +33,15 @@ namespace erpc { + + +/*! @brief Contents of the header that prefixes each message. */ +struct Header +{ + uint16_t m_messageSize; //!< Size in bytes of the message, excluding the header. + uint16_t m_crc; //!< CRC-16 over the message data. +}; + /*! * @brief Base class for framed transport layers. * @@ -95,13 +104,6 @@ class FramedTransport : public Transport */ virtual erpc_status_t send(MessageBuffer *message) override; - /*! @brief Contents of the header that prefixes each message. */ - struct Header - { - uint16_t m_messageSize; //!< Size in bytes of the message, excluding the header. - uint16_t m_crc; //!< CRC-16 over the message data. - }; - /*! * @brief This functions sets the CRC-16 implementation. *