diff --git a/CMakeLists.txt b/CMakeLists.txt index fcd9523..3a7962b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,12 @@ if (NOT CONFIG_MENDER_PLATFORM_TLS_TYPE) else() message(STATUS "Using custom '${CONFIG_MENDER_PLATFORM_TLS_TYPE}' platform TLS implementation") endif() +if (NOT CONFIG_MENDER_PLATFORM_SHA_TYPE) + message(STATUS "Using default 'generic/weak' platform SHA implementation") + set(CONFIG_MENDER_PLATFORM_SHA_TYPE "generic/weak") +else() + message(STATUS "Using custom '${CONFIG_MENDER_PLATFORM_SHA_TYPE}' platform SHA implementation") +endif() option(MENDER_MBEDTLS_ERROR_STR "Enable mbedtls error strings" OFF) @@ -168,6 +174,7 @@ file(GLOB SOURCES_TEMP "${CMAKE_CURRENT_LIST_DIR}/platform/scheduler/${CONFIG_MENDER_PLATFORM_SCHEDULER_TYPE}/src/mender-scheduler.c" "${CMAKE_CURRENT_LIST_DIR}/platform/storage/${CONFIG_MENDER_PLATFORM_STORAGE_TYPE}/src/mender-storage.c" "${CMAKE_CURRENT_LIST_DIR}/platform/tls/${CONFIG_MENDER_PLATFORM_TLS_TYPE}/src/mender-tls.c" + "${CMAKE_CURRENT_LIST_DIR}/platform/sha/${CONFIG_MENDER_PLATFORM_SHA_TYPE}/src/mender-sha.c" ) if (CONFIG_MENDER_CLIENT_INVENTORY) list(APPEND SOURCES_TEMP diff --git a/core/src/mender-artifact.c b/core/src/mender-artifact.c index ceb6c0f..0e0ea60 100644 --- a/core/src/mender-artifact.c +++ b/core/src/mender-artifact.c @@ -129,6 +129,10 @@ static mender_err_t mender_artifact_read_data(mender_artifact_ctx_t *ctx, mender */ static mender_err_t mender_artifact_drop_file(mender_artifact_ctx_t *ctx); +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT +static mender_err_t mender_artifact_read_header(mender_artifact_ctx_t *ctx); +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + /** * @brief Shift data after parsing * @param ctx Artifact context @@ -150,6 +154,108 @@ static size_t mender_artifact_round_up(size_t length, size_t incr); */ static mender_artifact_ctx_t *mender_artifact_ctx = NULL; +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT +/** + * @brief Get checksum entry for a file in the context + * @param ctx The mender artifact context + * @param filename The name of the file in the artifact + * @return The checksum entry or NULL on error. + * @note Since other files may be parsed before the manifest file, we need to + * create these entries in a lazy fashion. + */ +static mender_artifact_checksum_t * +mender_artifact_checksum_get_or_create(mender_artifact_ctx_t *ctx, const char *filename) { + assert(NULL != ctx); + assert(NULL != filename); + + /* See if we already have an entry for this file */ + mender_artifact_checksum_t *checksum; + for (checksum = ctx->artifact_info.checksums; NULL != checksum; checksum = checksum->next) { + if (StringEqual(checksum->filename, filename)) { + break; + } + } + + if (NULL == checksum) { + /* Create new if entry not found */ + checksum = (mender_artifact_checksum_t *)calloc(1, sizeof(mender_artifact_checksum_t)); + if (NULL == checksum) { + mender_log_error("Unable to allocate memory"); + return NULL; + } + checksum->filename = strdup(filename); + if (NULL == checksum->filename) { + mender_log_error("Unable to allocate memory"); + free(checksum); + return NULL; + } + checksum->next = ctx->artifact_info.checksums; + ctx->artifact_info.checksums = checksum; + + /* Start SHA-256 checksum computation (if not already started) */ + if (MENDER_OK != mender_sha256_begin(&(checksum->context))) { + mender_log_error("Failed to start checksum"); + return NULL; + } + } + + return checksum; +} +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + +mender_err_t +mender_artifact_check_integrity(mender_artifact_ctx_t *ctx) { + assert(NULL != ctx); + +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT + for (mender_artifact_checksum_t *checksum = ctx->artifact_info.checksums; NULL != checksum; checksum = checksum->next) { + unsigned char computed[MENDER_DIGEST_BUFFER_SIZE]; + + if (!StringEqual(checksum->filename, "version") && !StringEqual(checksum->filename, "header.tar") + && !mender_utils_strbeginwith(checksum->filename, "data/")) { + /* Whenever we introduce a new file to the artifact manifest, we + * need to skip integrity checks for that file until it's + * implemented. Otherwise, the client will get stuck trying to + * install the artifact which may hold the new implementation. */ + mender_log_warning("Skipping integrity check for artifact file '%s': Not implemented", checksum->filename); + continue; + } + mender_log_debug("Checking integrity for artifact file '%s'", checksum->filename); + + if (MENDER_OK != mender_sha256_finish(checksum->context, computed)) { + mender_log_error("Failed to finish checksum for file '%s'", checksum->filename); + checksum->context = NULL; + return MENDER_FAIL; + } + checksum->context = NULL; + + if (0 != memcmp(checksum->manifest, computed, MENDER_DIGEST_BUFFER_SIZE)) { + mender_log_error("Computed checksum for file '%s' does not match manifest", checksum->filename); +#if CONFIG_MENDER_LOG_LEVEL >= MENDER_LOG_LEVEL_DBG + /* Log the mismatching checksums for debugging */ + char checksum_str[(MENDER_DIGEST_BUFFER_SIZE * 2) + 1]; + + for (int i = 0; i < MENDER_DIGEST_BUFFER_SIZE; i++) { + if (2 != snprintf(checksum_str + (i * 2), 3, "%02hhx", checksum->manifest[i])) { + break; + } + } + mender_log_debug("%s: '%s' (manifest)", checksum->filename, checksum_str); + + for (int i = 0; i < MENDER_DIGEST_BUFFER_SIZE; i++) { + if (2 != snprintf(checksum_str + (i * 2), 3, "%02hhx", computed[i])) { + break; + } + } + mender_log_debug("%s: '%s' (computed)", checksum->filename, checksum_str); +#endif /* CONFIG_MENDER_LOG_LEVEL >= MENDER_LOG_LEVEL_DBG */ + return MENDER_FAIL; + } + } +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + return MENDER_OK; +} + mender_artifact_ctx_t * mender_artifact_create_ctx(void) { @@ -270,7 +376,10 @@ mender_artifact_process_data(mender_artifact_ctx_t *ctx, /* Drop data, file is not relevant */ ret = mender_artifact_drop_file(ctx); - +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT + } else if (StringEqual(ctx->file.name, "header.tar")) { + ret = mender_artifact_read_header(ctx); +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ } else { /* Nothing to do */ @@ -325,7 +434,10 @@ mender_artifact_release_ctx(mender_artifact_ctx_t *ctx) { #ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT mender_utils_free_linked_list(ctx->artifact_info.provides); mender_utils_free_linked_list(ctx->artifact_info.depends); - mender_utils_free_linked_list(ctx->artifact_info.checksums); + for (mender_artifact_checksum_t *checksum = ctx->artifact_info.checksums; NULL != checksum; checksum = checksum->next) { + free(checksum->filename); + mender_sha256_finish(checksum->context, NULL); + } #endif free(ctx); } @@ -440,6 +552,21 @@ mender_artifact_read_version(mender_artifact_ctx_t *ctx) { return MENDER_OK; } +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT + /* Get checksum entry (create one if needed) */ + mender_artifact_checksum_t *checksum; + if (NULL == (checksum = mender_artifact_checksum_get_or_create(ctx, "version"))) { + /* Error already logged */ + return MENDER_FAIL; + } + + /* Update SHA-256 checksum */ + if (MENDER_OK != mender_sha256_update(checksum->context, ctx->input.data, ctx->file.size)) { + mender_log_error("Failed to update update checksum"); + return MENDER_FAIL; + } +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + /* Check version file */ if (NULL == (object = cJSON_ParseWithLength(ctx->input.data, ctx->file.size))) { mender_log_error("Unable to allocate memory"); @@ -532,31 +659,40 @@ mender_artifact_read_manifest(mender_artifact_ctx_t *ctx) { } *next = '\0'; - ///* Process line */ + /* Process line */ char *separator = strstr(line, " "); if (NULL == separator) { mender_log_error("Invalid manifest file"); return MENDER_FAIL; } + *separator = '\0'; - /* Add checksum to the list */ - mender_key_value_list_t *checksum = (mender_key_value_list_t *)calloc(1, sizeof(mender_key_value_list_t)); - if (NULL == checksum) { - mender_log_error("Unable to allocate memory"); + const char *checksum_str = line; + const char *filename = separator + 2; + + /* Useful when debugging artifact integrity check failures */ + mender_log_debug("%s %s", checksum_str, filename); + + /* Make sure digest is of expected length (two hex per byte) */ + if ((MENDER_DIGEST_BUFFER_SIZE * 2) != strlen(checksum_str)) { + mender_log_error("Bad checksum '%s' in manifest for file '%s'", checksum_str, filename); return MENDER_FAIL; } - *separator = '\0'; - /* Allocate memory and check if allocation was succesfull */ - checksum->key = strdup(line); - checksum->value = strdup(separator + 2); - if ((NULL == checksum->key) || (NULL == checksum->value)) { - mender_log_error("Unable to allocate memory"); - mender_utils_free_linked_list(checksum); + /* Get checksum entry for the file (creates one if not found) */ + mender_artifact_checksum_t *checksum; + if (NULL == (checksum = mender_artifact_checksum_get_or_create(ctx, filename))) { + /* Error already logged */ return MENDER_FAIL; } - checksum->next = ctx->artifact_info.checksums; - ctx->artifact_info.checksums = checksum; + + /* Populate with manifest checksum */ + for (int i = 0; i < MENDER_DIGEST_BUFFER_SIZE; i++) { + if (1 != sscanf(checksum_str + (2 * i), "%02hhx", checksum->manifest + i)) { + mender_log_error("Bad checksum '%s' in manifest for file '%s'", checksum_str, filename); + return MENDER_FAIL; + } + } ///* Move to the next line */ line = next + 1; @@ -699,6 +835,33 @@ mender_artifact_read_header_info(mender_artifact_ctx_t *ctx) { return ret; } +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT +static mender_err_t +mender_artifact_read_header(mender_artifact_ctx_t *ctx) { + assert(NULL != ctx); + + /* Check if all data have been received */ + if ((NULL == ctx->input.data) || (ctx->input.length < mender_artifact_round_up(ctx->file.size, MENDER_ARTIFACT_STREAM_BLOCK_SIZE))) { + return MENDER_OK; + } + + /* Get checksum entry (create one if needed) */ + mender_artifact_checksum_t *checksum; + if (NULL == (checksum = mender_artifact_checksum_get_or_create(ctx, "header.tar"))) { + /* Error already logged */ + return MENDER_FAIL; + } + + /* Update SHA-256 checksum */ + if (MENDER_OK != mender_sha256_update(checksum->context, ctx->input.data, ctx->file.size)) { + mender_log_error("Failed to update update checksum"); + return MENDER_FAIL; + } + + return MENDER_DONE; +} +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + #ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT static mender_err_t mender_artifact_read_type_info(mender_artifact_ctx_t *ctx) { @@ -910,6 +1073,37 @@ mender_artifact_read_data(mender_artifact_ctx_t *ctx, mender_err_t (*callback)(c size_t length = ((ctx->file.size - ctx->file.index) > MENDER_ARTIFACT_STREAM_BLOCK_SIZE) ? MENDER_ARTIFACT_STREAM_BLOCK_SIZE : (ctx->file.size - ctx->file.index); +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT + mender_artifact_checksum_t *checksum; + { + /* The filename will be something like + * 'data/0000.tar/zephyr.signed.bin'. But the manifest will hold + * 'data/0000/zephyr.signed.bin'. Hence, we need to remove the + * '.tar' extension from the string. + */ + char filename[strlen(ctx->file.name) + 1]; + strcpy(filename, ctx->file.name); + + for (char *ch = strstr(filename, ".tar"); (NULL != ch) && (*ch != '\0'); ch++) { + /* Don't worry! The call to strlen() on a static string should + * be optimized out by the compiler */ + *ch = ch[strlen(".tar")]; + } + + /* Get checksum entry (create one if needed) */ + if (NULL == (checksum = mender_artifact_checksum_get_or_create(ctx, filename))) { + /* Error already logged */ + return MENDER_FAIL; + } + } + + /* Update SHA-256 checksum */ + if (MENDER_OK != mender_sha256_update(checksum->context, ctx->input.data, length)) { + mender_log_error("Failed to update update checksum"); + return MENDER_FAIL; + } +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + /* Invoke callback */ if (MENDER_OK != (ret = callback(ctx->payloads.values[index].type, diff --git a/core/src/mender-client.c b/core/src/mender-client.c index 717bdc8..1c707bb 100644 --- a/core/src/mender-client.c +++ b/core/src/mender-client.c @@ -990,24 +990,26 @@ mender_client_update_work_function(void) { /* Get artifact context if artifact download succeeded */ if ((NULL != mender_update_module) && (MENDER_OK == (ret = mender_artifact_get_ctx(&mender_artifact_ctx)))) { #ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT - if (MENDER_OK == (ret = mender_check_artifact_requirements(mender_artifact_ctx, deployment))) { + if (MENDER_OK == (ret = mender_artifact_check_integrity(mender_artifact_ctx))) { + if (MENDER_OK == (ret = mender_check_artifact_requirements(mender_artifact_ctx, deployment))) { #ifdef CONFIG_MENDER_PROVIDES_DEPENDS - /* Add the new provides to the deployment data (we need the artifact context) */ - char *new_provides = NULL; - const char *artifact_name = NULL; - if (MENDER_OK == (ret = mender_prepare_new_provides(mender_artifact_ctx, &new_provides, &artifact_name))) { - if (MENDER_OK != (ret = mender_deployment_data_set_provides(mender_client_deployment_data, new_provides))) { - mender_log_error("Failed to set deployment data provides"); + /* Add the new provides to the deployment data (we need the artifact context) */ + char *new_provides = NULL; + const char *artifact_name = NULL; + if (MENDER_OK == (ret = mender_prepare_new_provides(mender_artifact_ctx, &new_provides, &artifact_name))) { + if (MENDER_OK != (ret = mender_deployment_data_set_provides(mender_client_deployment_data, new_provides))) { + mender_log_error("Failed to set deployment data provides"); + } + /* Replace artifact_name with the one from provides */ + else if (MENDER_OK != (ret = mender_deployment_data_set_artifact_name(mender_client_deployment_data, artifact_name))) { + mender_log_error("Failed to set deployment data artifact name"); + } + free(new_provides); + } else { + mender_log_error("Unable to prepare new provides"); } - /* Replace artifact_name with the one from provides */ - else if (MENDER_OK != (ret = mender_deployment_data_set_artifact_name(mender_client_deployment_data, artifact_name))) { - mender_log_error("Failed to set deployment data artifact name"); - } - free(new_provides); - } else { - mender_log_error("Unable to prepare new provides"); - } #endif /* CONFIG_MENDER_PROVIDES_DEPENDS */ + } } #endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ } else { diff --git a/include/mender-artifact.h b/include/mender-artifact.h index 9cb02a8..72d486e 100644 --- a/include/mender-artifact.h +++ b/include/mender-artifact.h @@ -25,6 +25,7 @@ extern "C" { #endif /* __cplusplus */ #include "mender-utils.h" +#include "mender-sha.h" /** * @brief Artifact state machine used to process input data stream @@ -50,6 +51,16 @@ typedef struct { cJSON *meta_data; /**< Meta-data from the header tarball, NULL if no meta-data */ } mender_artifact_payload_t; +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT +typedef struct mender_artifact_checksum_t mender_artifact_checksum_t; +struct mender_artifact_checksum_t { + char *filename; + unsigned char manifest[MENDER_DIGEST_BUFFER_SIZE]; + mender_sha256_context_t context; + mender_artifact_checksum_t *next; +}; +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + /** * @brief Artifact context */ @@ -65,11 +76,11 @@ typedef struct { } payloads; /**< Payloads of the artifact */ #ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT struct { - mender_key_value_list_t *checksums; /**< Contains checksums of the artifact */ - mender_key_value_list_t *provides; /**< Provides of the artifact */ - mender_key_value_list_t *depends; /**< Depends of the artifact */ - } artifact_info; /**< Global information about the artifact */ -#endif + mender_artifact_checksum_t *checksums; /**< Contains checksums of the artifact */ + mender_key_value_list_t *provides; /**< Provides of the artifact */ + mender_key_value_list_t *depends; /**< Depends of the artifact */ + } artifact_info; /**< Global information about the artifact */ +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ struct { char *name; /**< Name of the file currently parsed */ size_t size; /**< Size of the file currently parsed (bytes) */ @@ -94,7 +105,7 @@ mender_err_t mender_artifact_get_device_type(mender_artifact_ctx_t *ctx, const c mender_artifact_ctx_t *mender_artifact_create_ctx(void); /** - * @brief Function used to create a new artifact context + * @brief Function used to get the artifact context * @return MENDER_OK if the function succeeds, error code otherwise */ mender_err_t mender_artifact_get_ctx(mender_artifact_ctx_t **ctx); @@ -112,6 +123,14 @@ mender_err_t mender_artifact_process_data(mender_artifact_ctx_t *ctx, size_t input_length, mender_err_t (*callback)(char *, cJSON *, char *, size_t, void *, size_t, size_t)); +/** + * @brief Do integrity checks by comparing the manifest checksums to the computed ones + * @param ctx Artifact context + * @return MENDER_OK if integrity is enforced, error code otherwise + * @note Call the after the processing of data from artifact stream is complete + */ +mender_err_t mender_artifact_check_integrity(mender_artifact_ctx_t *ctx); + /** * @brief Function used to release artifact context * @param ctx Artifact context diff --git a/include/mender-sha.h b/include/mender-sha.h new file mode 100644 index 0000000..36e668c --- /dev/null +++ b/include/mender-sha.h @@ -0,0 +1,76 @@ +/** + * @file mender-sha.h + * @brief Mender SHA interface + * + * Copyright Northern.tech AS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MENDER_SHA_H__ +#define __MENDER_SHA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "mender-utils.h" /* mender_err_t */ + +/** + * @brief This type is just a pointer to whatever data structure is required by + * a specific platform implementation. This data structure will be + * allocated on the heap by mender_sha256_begin function and must be + * free'd in the mender_sha256_finish function. + */ +typedef void *mender_sha256_context_t; + +/** + * @brief Size of SHA-256 buffer in Bytes. + */ +#define MENDER_DIGEST_BUFFER_SIZE 32 + +/** + * @brief Initializes a SHA-256 context and starts a checksum calculation. + * @param context The SHA-256 context to be initialized. This must not be NULL. + * @note A call to mender_sha256_begin must be followed by a call to + * mender_sha256_finish in order to release resources. + * @return MENDER_OK on success, otherwise error code. + */ +mender_err_t mender_sha256_begin(mender_sha256_context_t *context); + +/** + * @brief Feeds an input buffer into an ongoing SHA-256 checksum calculation. + * @param context The SHA-256 context. This must have been initialized. + * @param input The buffer holding the data to be fed. + * @param length The length of the input data in Bytes. + * @return MENDER_OK on success, otherwise error code. + */ +mender_err_t mender_sha256_update(mender_sha256_context_t context, const unsigned char *input, size_t length); + +/** + * @brief Finishes the SHA-256 checksum calculation, writes the result to the + * output buffer and clears the SHA-256 context. + * @param context The SHA-256 context to be cleared. If NULL is passed, no + * operation is performed. + * @param output A writeable buffer of MENDER_DIGEST_BUFFER_SIZE Bytes for + * SHA-256 checksum. If NULL is passed, the function will only + * clear the SHA-256 context. + * @return MENDER_OK on success, otherwise error code. + */ +mender_err_t mender_sha256_finish(mender_sha256_context_t context, unsigned char *output); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MENDER_SHA_H__ */ diff --git a/platform/sha/generic/mbedtls/src/mender-sha.c b/platform/sha/generic/mbedtls/src/mender-sha.c new file mode 100644 index 0000000..bda124f --- /dev/null +++ b/platform/sha/generic/mbedtls/src/mender-sha.c @@ -0,0 +1,63 @@ +/** + * @file mender-sha.c + * @brief Mender SHA interface for MbedTLS platform + * + * Copyright Northern.tech AS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mender-sha.h" +#include "mender-log.h" + +#include + +mender_err_t +mender_sha256_begin(mender_sha256_context_t *context) { + assert(NULL != context); + + mbedtls_sha256_context *ctx = malloc(sizeof(mbedtls_sha256_context)); + if (NULL == ctx) { + mender_log_error("Unable to allocate memory"); + return MENDER_FAIL; + } + + mbedtls_sha256_init(ctx); + mbedtls_sha256_starts(ctx, 0); /* Use SHA-256, not SHA-224 */ + + *context = ctx; + return MENDER_OK; +} + +mender_err_t +mender_sha256_update(mender_sha256_context_t context, const unsigned char *input, size_t length) { + assert(NULL != context); + + mbedtls_sha256_context *ctx = context; + mbedtls_sha256_update(ctx, input, length); + + return MENDER_OK; +} + +mender_err_t +mender_sha256_finish(mender_sha256_context_t context, unsigned char *output) { + mbedtls_sha256_context *ctx = context; + if (NULL != ctx) { + if (NULL != output) { + mbedtls_sha256_finish(ctx, output); + } + mbedtls_sha256_free(ctx); + free(ctx); + } + return MENDER_OK; +} diff --git a/platform/sha/generic/weak/src/mender-sha.c b/platform/sha/generic/weak/src/mender-sha.c new file mode 100644 index 0000000..d1f8d3d --- /dev/null +++ b/platform/sha/generic/weak/src/mender-sha.c @@ -0,0 +1,38 @@ +/** + * @file mender-sha.c + * @brief Mender SHA interface for weak platform + * + * Copyright Northern.tech AS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mender-sha.h" + +__attribute__((weak)) mender_err_t +mender_sha256_begin(MENDER_ARG_UNUSED mender_sha256_context_t *ctx) { + /* Nothing to do */ + return MENDER_NOT_IMPLEMENTED; +} + +__attribute__((weak)) mender_err_t +mender_sha256_update(MENDER_ARG_UNUSED mender_sha256_context_t ctx, MENDER_ARG_UNUSED const unsigned char *input, MENDER_ARG_UNUSED size_t length) { + /* Nothing to do */ + return MENDER_NOT_IMPLEMENTED; +} + +__attribute__((weak)) mender_err_t +mender_sha256_finish(MENDER_ARG_UNUSED mender_sha256_context_t ctx, MENDER_ARG_UNUSED unsigned char *output) { + /* Nothing to do */ + return MENDER_NOT_IMPLEMENTED; +} diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 97df53a..1a55734 100755 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -29,6 +29,7 @@ if(CONFIG_MENDER_MCU_CLIENT) "${CMAKE_CURRENT_LIST_DIR}/../platform/scheduler/${CONFIG_MENDER_PLATFORM_SCHEDULER_TYPE}/src/mender-scheduler.c" "${CMAKE_CURRENT_LIST_DIR}/../platform/storage/${CONFIG_MENDER_PLATFORM_STORAGE_TYPE}/src/mender-storage.c" "${CMAKE_CURRENT_LIST_DIR}/../platform/tls/${CONFIG_MENDER_PLATFORM_TLS_TYPE}/src/mender-tls.c" + "${CMAKE_CURRENT_LIST_DIR}/../platform/sha/${CONFIG_MENDER_PLATFORM_TLS_TYPE}/src/mender-sha.c" ) zephyr_library_sources_ifdef(CONFIG_MENDER_CLIENT_INVENTORY "${CMAKE_CURRENT_LIST_DIR}/../core/src/mender-inventory.c" diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 7f21cd2..29747ae 100755 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -212,6 +212,24 @@ if MENDER_MCU_CLIENT default "generic/mbedtls" if MENDER_PLATFORM_TLS_TYPE_MBEDTLS default "generic/weak" if MENDER_PLATFORM_TLS_TYPE_WEAK + choice MENDER_PLATFORM_SHA_TYPE + prompt "Mender platform SHA implementation type" + default MENDER_PLATFORM_SHA_TYPE_MBEDTLS + help + Specify platform SHA implementation type, select 'weak' to use you own implementation. + + config MENDER_PLATFORM_SHA_TYPE_MBEDTLS + bool "mbedtls" + select MBEDTLS + config MENDER_PLATFORM_SHA_TYPE_WEAK + bool "weak" + endchoice + + config MENDER_PLATFORM_SHA_TYPE + string + default "generic/mbedtls" if MENDER_PLATFORM_SHA_TYPE_MBEDTLS + default "generic/weak" if MENDER_PLATFORM_SHA_TYPE_WEAK + endmenu if MENDER_PLATFORM_NET_TYPE_DEFAULT