1 /*
2  * Copyright (c) 2023 O.S.Systems
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL);
9 
10 #include "updatehub_integrity.h"
11 
updatehub_integrity_init(struct updatehub_crypto_context * ctx)12 int updatehub_integrity_init(struct updatehub_crypto_context *ctx)
13 {
14 	int ret;
15 
16 	if (ctx == NULL) {
17 		LOG_DBG("Invalid integrity context");
18 		return -EINVAL;
19 	}
20 
21 	memset(ctx, 0, sizeof(struct updatehub_crypto_context));
22 
23 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS)
24 	ctx->md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
25 	if (ctx->md_info == NULL) {
26 		LOG_DBG("Message Digest not found or not enabled");
27 		return -ENOENT;
28 	}
29 
30 	mbedtls_md_init(&ctx->md_ctx);
31 	ret = mbedtls_md_setup(&ctx->md_ctx, ctx->md_info, 0);
32 	if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) {
33 		LOG_DBG("Bad Message Digest selected");
34 		return -EFAULT;
35 	}
36 	if (ret == MBEDTLS_ERR_MD_ALLOC_FAILED) {
37 		LOG_DBG("Failed to allocate memory");
38 		return -ENOMEM;
39 	}
40 
41 	ret = mbedtls_md_starts(&ctx->md_ctx);
42 	if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) {
43 		LOG_DBG("Bad Message Digest selected");
44 		return -EFAULT;
45 	}
46 #elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
47 	ret = tc_sha256_init(&ctx->sha256sum);
48 	if (ret != TC_CRYPTO_SUCCESS) {
49 		LOG_DBG("Invalid integrity context");
50 		return -EFAULT;
51 	}
52 #endif
53 
54 	return 0;
55 }
56 
updatehub_integrity_update(struct updatehub_crypto_context * ctx,const uint8_t * buffer,const uint32_t len)57 int updatehub_integrity_update(struct updatehub_crypto_context *ctx,
58 			       const uint8_t *buffer, const uint32_t len)
59 {
60 	int ret;
61 
62 	if (ctx == NULL || buffer == NULL) {
63 		return -EINVAL;
64 	}
65 
66 	/* bypass */
67 	if (len == 0) {
68 		return 0;
69 	}
70 
71 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS)
72 	ret = mbedtls_md_update(&ctx->md_ctx, buffer, len);
73 	if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) {
74 		LOG_DBG("Bad Message Digest selected");
75 		return -EFAULT;
76 	}
77 #elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
78 	ret = tc_sha256_update(&ctx->sha256sum, buffer, len);
79 	if (ret != TC_CRYPTO_SUCCESS) {
80 		LOG_DBG("Invalid integrity context or invalid buffer");
81 		return -EFAULT;
82 	}
83 #endif
84 
85 	return 0;
86 }
87 
updatehub_integrity_finish(struct updatehub_crypto_context * ctx,uint8_t * hash,const uint32_t size)88 int updatehub_integrity_finish(struct updatehub_crypto_context *ctx,
89 			       uint8_t *hash, const uint32_t size)
90 {
91 	int ret;
92 
93 	if (ctx == NULL || hash == NULL) {
94 		return -EINVAL;
95 	}
96 
97 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS)
98 	if (size < mbedtls_md_get_size(ctx->md_info)) {
99 		LOG_DBG("HASH input buffer is to small to store the message digest");
100 		return -EINVAL;
101 	}
102 
103 	ret = mbedtls_md_finish(&ctx->md_ctx, hash);
104 	if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) {
105 		LOG_DBG("Bad Message Digest selected");
106 		return -EFAULT;
107 	}
108 
109 	mbedtls_md_free(&ctx->md_ctx);
110 #elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
111 	ret = tc_sha256_final(hash, &ctx->sha256sum);
112 	if (ret != TC_CRYPTO_SUCCESS) {
113 		LOG_DBG("Invalid integrity context or invalid hash pointer");
114 		return -EFAULT;
115 	}
116 #endif
117 
118 	return 0;
119 }
120