Skip to content
This repository was archived by the owner on Dec 26, 2022. It is now read-only.

Commit f84e8ba

Browse files
committed
feat(mam): Add PSK for channel encryption
Sender/Receiver can assign multiple PSK keys to de/encrypt a MAM channel.
1 parent 0941fc9 commit f84e8ba

File tree

13 files changed

+229
-106
lines changed

13 files changed

+229
-106
lines changed

accelerator/core/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ cc_library(
6363
"//accelerator/core",
6464
"//accelerator/core/request",
6565
"//accelerator/core/response",
66+
"//utils:fill_nines",
67+
"//utils:tryte_byte_conv",
6668
"@entangled//common/trinary:flex_trit",
6769
"@entangled//mam/api",
6870
"@entangled//utils/containers/hash:hash_array",

accelerator/core/mam_core.c

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "accelerator/core/mam_core.h"
1010
#include "common/model/transfer.h"
1111
#include "utils/containers/hash/hash_array.h"
12+
#include "utils/fill_nines.h"
13+
#include "utils/tryte_byte_conv.h"
1214

1315
#define MAM_LOGGER "mam_core"
1416

@@ -161,26 +163,53 @@ static mam_endpoint_t *mam_api_endpoint_get(mam_api_t const *const api, tryte_t
161163
return NULL;
162164
}
163165

166+
/**
167+
* @brief Free 'mam_encrypt_key_t' object
168+
*
169+
* @param mam_key[in] 'mam_encrypt_key_t' object to be freed
170+
*
171+
* @return status code
172+
*/
173+
static inline void mam_encrypt_key_free(mam_encrypt_key_t *mam_key) {
174+
mam_psk_t_set_free(&mam_key->psks);
175+
mam_ntru_pk_t_set_free(&mam_key->ntru_pks);
176+
mam_ntru_sk_t_set_free(&mam_key->ntru_sks);
177+
}
178+
164179
/**
165180
* @brief Add all the keys in the list of Pre-Shared Key and NTRU public key into corresponding key set.
166181
*
167-
* @param psks[in] Pre-Shared Key set
168-
* @param ntru_pks[in] NTRU public key set
182+
* The PSK keys are converting the index into trytes as PSK ID.
183+
*
184+
* @param psks[out] Pre-Shared Key set
185+
* @param ntru_pks[out] NTRU public key set
169186
* @param psk[in] List of Pre-Shared Key
170187
* @param ntru_pk[in] List of NTRU public key
171188
*
172189
* @return status code
173190
*/
174-
static status_t ta_set_mam_key(mam_psk_t_set_t *const psks, mam_ntru_pk_t_set_t *const ntru_pks,
175-
UT_array const *const psk, UT_array const *const ntru_pk) {
191+
static status_t ta_set_mam_key(mam_encrypt_key_t *const mam_keys, UT_array const *const psk,
192+
UT_array const *const ntru_pk, UT_array const *const ntru_sk) {
193+
status_t ret = SC_OK;
176194
char **p = NULL;
177195
if (psk) {
178196
mam_psk_t psk_obj;
197+
uint16_t psk_id_cnt = 0;
179198
while ((p = (char **)utarray_next(psk, p))) {
199+
tryte_t raw_psk_id[NUM_TRYTES_MAM_PSK_ID_SIZE + 1] = {}, psk_id[NUM_TRYTES_MAM_PSK_ID_SIZE + 1] = {};
200+
bytes_to_trytes((unsigned char *)&psk_id_cnt, sizeof(psk_id_cnt) / sizeof(char), (char *)raw_psk_id);
201+
ret = fill_nines((char *)psk_id, (char *)raw_psk_id, NUM_TRYTES_MAM_PSK_ID_SIZE);
202+
if (ret) {
203+
ta_log_error("%s\n", ta_error_to_string(ret));
204+
return ret;
205+
}
206+
207+
trytes_to_trits((tryte_t *)psk_id, psk_obj.id, NUM_TRYTES_MAM_PSK_ID_SIZE);
180208
trytes_to_trits((tryte_t *)*p, psk_obj.key, NUM_TRYTES_MAM_PSK_KEY_SIZE);
181-
if (mam_psk_t_set_add(psks, &psk_obj) != RC_OK) {
182-
ta_log_error("%s\n", "SC_MAM_FAILED_INIT");
183-
return SC_MAM_FAILED_INIT;
209+
if (mam_psk_t_set_add(&mam_keys->psks, &psk_obj) != RC_OK) {
210+
ret = SC_MAM_FAILED_INIT;
211+
ta_log_error("%s\n", ta_error_to_string(ret));
212+
return ret;
184213
}
185214
}
186215
}
@@ -189,9 +218,22 @@ static status_t ta_set_mam_key(mam_psk_t_set_t *const psks, mam_ntru_pk_t_set_t
189218
mam_ntru_pk_t ntru_pk_obj;
190219
while ((p = (char **)utarray_next(ntru_pk, p))) {
191220
trytes_to_trits((tryte_t *)*p, ntru_pk_obj.key, NUM_TRYTES_MAM_NTRU_PK_SIZE);
192-
if (mam_ntru_pk_t_set_add(ntru_pks, &ntru_pk_obj) != RC_OK) {
193-
ta_log_error("%s\n", "SC_MAM_FAILED_INIT");
194-
return SC_MAM_FAILED_INIT;
221+
if (mam_ntru_pk_t_set_add(&mam_keys->ntru_pks, &ntru_pk_obj) != RC_OK) {
222+
ret = SC_MAM_FAILED_INIT;
223+
ta_log_error("%s\n", ta_error_to_string(ret));
224+
return ret;
225+
}
226+
}
227+
}
228+
229+
if (ntru_sk) {
230+
mam_ntru_sk_t ntru_sk_obj;
231+
while ((p = (char **)utarray_next(ntru_sk, p))) {
232+
trytes_to_trits((tryte_t *)*p, ntru_sk_obj.secret_key, NUM_TRYTES_MAM_NTRU_SK_SIZE);
233+
if (mam_ntru_sk_t_set_add(&mam_keys->ntru_sks, &ntru_sk_obj) != RC_OK) {
234+
ret = SC_MAM_FAILED_INIT;
235+
ta_log_error("%s\n", ta_error_to_string(ret));
236+
return ret;
195237
}
196238
}
197239
}
@@ -528,7 +570,8 @@ status_t ta_send_mam_message(const ta_config_t *const info, const iota_config_t
528570
tryte_t chid[MAM_CHANNEL_ID_TRYTE_SIZE] = {}, msg_id[NUM_TRYTES_MAM_MSG_ID] = {};
529571
bundle_transactions_t *bundle = NULL;
530572
send_mam_data_mam_v1_t *data = (send_mam_data_mam_v1_t *)req->data;
531-
mam_encrypt_key_t mam_key = {.psks = NULL, .ntru_pks = NULL};
573+
send_mam_key_mam_v1_t *key = (send_mam_key_mam_v1_t *)req->key;
574+
mam_encrypt_key_t mam_key = {.psks = NULL, .ntru_pks = NULL, .ntru_sks = NULL};
532575
bool msg_sent = false;
533576

534577
// Creating MAM API
@@ -538,6 +581,12 @@ status_t ta_send_mam_message(const ta_config_t *const info, const iota_config_t
538581
goto done;
539582
}
540583

584+
ret = ta_set_mam_key(&mam_key, key->psk_array, key->ntru_array, NULL);
585+
if (ret) {
586+
ta_log_error("%s\n", ta_error_to_string(ret));
587+
goto done;
588+
}
589+
541590
mam_send_operation_t mam_operation;
542591
while (!msg_sent) {
543592
bundle_transactions_renew(&bundle);
@@ -608,7 +657,7 @@ status_t ta_send_mam_message(const ta_config_t *const info, const iota_config_t
608657
}
609658
}
610659
bundle_transactions_free(&bundle);
611-
660+
mam_encrypt_key_free(&mam_key);
612661
return ret;
613662
}
614663

@@ -619,6 +668,7 @@ status_t ta_recv_mam_message(const iota_config_t *const iconf, const iota_client
619668
bundle_array_t *bundle_array = NULL;
620669
bundle_array_new(&bundle_array);
621670
recv_mam_data_id_mam_v1_t *data_id = (recv_mam_data_id_mam_v1_t *)req->data_id;
671+
recv_mam_key_mam_v1_t *key = (recv_mam_key_mam_v1_t *)req->key;
622672
if (mam_api_init(&mam, (tryte_t *)iconf->seed) != RC_OK) {
623673
ret = SC_MAM_FAILED_INIT;
624674
ta_log_error("%s\n", ta_error_to_string(ret));
@@ -652,6 +702,23 @@ status_t ta_recv_mam_message(const iota_config_t *const iconf, const iota_client
652702
}
653703
}
654704

705+
// Add decryption keys
706+
mam_encrypt_key_t mam_key = {.psks = NULL, .ntru_pks = NULL, .ntru_sks = NULL};
707+
ret = ta_set_mam_key(&mam_key, key->psk_array, NULL, key->ntru_array);
708+
if (ret != SC_OK) {
709+
ta_log_error("%s\n", ta_error_to_string(ret));
710+
goto done;
711+
}
712+
713+
mam_psk_t_set_entry_t *curr_psk_p = NULL;
714+
mam_psk_t_set_entry_t *tmp_psk_p = NULL;
715+
HASH_ITER(hh, mam_key.psks, curr_psk_p, tmp_psk_p) {
716+
if (mam_api_add_psk(&mam, &curr_psk_p->value)) {
717+
ta_log_error("%s\n", "Failed to add PSK keys");
718+
goto done;
719+
}
720+
}
721+
655722
// Copy the trusted_channel_pks, before fetching the information from MAM.
656723
mam_pk_t_set_t init_trusted_ch = NULL;
657724
mam_pk_t_set_entry_t *curr_entry = NULL;
@@ -694,5 +761,6 @@ status_t ta_recv_mam_message(const iota_config_t *const iconf, const iota_client
694761
}
695762
bundle_array_free(&bundle_array);
696763
mam_pk_t_set_free(&init_trusted_ch);
764+
mam_encrypt_key_free(&mam_key);
697765
return ret;
698766
}

accelerator/core/mam_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef enum mam_send_operation_e { ANNOUNCE_CHID, SEND_MESSAGE } mam_send_opera
4444
typedef struct mam_encrypt_key_s {
4545
mam_psk_t_set_t psks;
4646
mam_ntru_pk_t_set_t ntru_pks;
47+
mam_ntru_sk_t_set_t ntru_sks;
4748
} mam_encrypt_key_t;
4849

4950
/**

accelerator/core/request/ta_recv_mam.c

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ static void recv_mam_req_v1_free(ta_recv_mam_req_t** req) {
3434

3535
if ((*req)->key) {
3636
recv_mam_key_mam_v1_t* key = (*req)->key;
37-
free(key->enc_key);
37+
utarray_free(key->psk_array);
38+
utarray_free(key->ntru_array);
3839
free(key);
3940
(*req)->key = NULL;
4041
}
@@ -58,21 +59,39 @@ void recv_mam_req_free(ta_recv_mam_req_t** req) {
5859
*req = NULL;
5960
}
6061

61-
status_t recv_mam_set_mam_v1_data_id(ta_recv_mam_req_t* req, char* bundle_hash, char* chid, char* msg_id) {
62-
if (req == NULL || (!bundle_hash && !chid && !msg_id)) {
62+
status_t recv_mam_req_v1_init(ta_recv_mam_req_t* req) {
63+
if (req == NULL) {
6364
return SC_TA_NULL;
6465
}
65-
status_t ret = SC_OK;
6666

6767
req->data_id = (recv_mam_data_id_mam_v1_t*)malloc(sizeof(recv_mam_data_id_mam_v1_t));
68-
if (!req->data_id) {
68+
if (req->data_id == NULL) {
69+
return SC_TA_OOM;
70+
}
71+
req->key = (recv_mam_key_mam_v1_t*)malloc(sizeof(recv_mam_key_mam_v1_t));
72+
if (req->key == NULL) {
6973
return SC_TA_OOM;
7074
}
7175

7276
recv_mam_data_id_mam_v1_t* data_id = (recv_mam_data_id_mam_v1_t*)req->data_id;
7377
data_id->bundle_hash = NULL;
7478
data_id->chid = NULL;
7579
data_id->msg_id = NULL;
80+
81+
recv_mam_key_mam_v1_t* key = (recv_mam_key_mam_v1_t*)req->key;
82+
utarray_new(key->psk_array, &ut_str_icd);
83+
utarray_new(key->ntru_array, &ut_str_icd);
84+
85+
return SC_OK;
86+
}
87+
88+
status_t recv_mam_set_mam_v1_data_id(ta_recv_mam_req_t* req, char* bundle_hash, char* chid, char* msg_id) {
89+
if (req == NULL || (!bundle_hash && !chid && !msg_id)) {
90+
return SC_TA_NULL;
91+
}
92+
status_t ret = SC_OK;
93+
94+
recv_mam_data_id_mam_v1_t* data_id = (recv_mam_data_id_mam_v1_t*)req->data_id;
7695
if (bundle_hash) {
7796
data_id->bundle_hash = (tryte_t*)strdup(bundle_hash);
7897
if (!data_id->bundle_hash) {
@@ -98,38 +117,8 @@ status_t recv_mam_set_mam_v1_data_id(ta_recv_mam_req_t* req, char* bundle_hash,
98117
return ret;
99118

100119
error:
101-
free(req->data_id);
102-
req->data_id = NULL;
120+
free(data_id->bundle_hash);
121+
free(data_id->chid);
122+
free(data_id->msg_id);
103123
return ret;
104124
}
105-
106-
status_t recv_mam_set_mam_v1_key(ta_recv_mam_req_t* req, tryte_t* psk, tryte_t* ntru) {
107-
if (!req) {
108-
return SC_TA_NULL;
109-
}
110-
111-
req->key = (recv_mam_key_mam_v1_t*)malloc(sizeof(recv_mam_key_mam_v1_t));
112-
if (!req->key) {
113-
return SC_TA_OOM;
114-
}
115-
116-
recv_mam_key_mam_v1_t* key = (recv_mam_key_mam_v1_t*)req->key;
117-
// We will set either psk or ntru, so initializing both fields will avoid errors in the future.
118-
key->enc_key = NULL;
119-
120-
if (psk) {
121-
key->enc_key = (tryte_t*)malloc(sizeof(tryte_t) * NUM_TRYTES_MAM_PSK_KEY_SIZE);
122-
if (!key->enc_key) {
123-
return SC_TA_OOM;
124-
}
125-
memcpy(key->enc_key, psk, sizeof(tryte_t) * NUM_TRYTES_MAM_PSK_KEY_SIZE);
126-
} else if (ntru) {
127-
key->enc_key = (tryte_t*)malloc(sizeof(tryte_t) * NUM_TRYTES_MAM_NTRU_PK_SIZE);
128-
if (!key->enc_key) {
129-
return SC_TA_OOM;
130-
}
131-
memcpy(key->enc_key, ntru, sizeof(tryte_t) * NUM_TRYTES_MAM_NTRU_PK_SIZE);
132-
}
133-
134-
return SC_OK;
135-
}

accelerator/core/request/ta_recv_mam.h

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ ta_recv_mam_req_t* recv_mam_req_new();
4444
/**
4545
* Free memory of ta_recv_mam_req_t
4646
*
47-
* @param req Data type of ta_recv_mam_req_t
47+
* @param req[out] Data type of ta_recv_mam_req_t
4848
*/
4949
void recv_mam_req_free(ta_recv_mam_req_t** req);
5050

@@ -60,18 +60,19 @@ typedef struct recv_mam_data_id_mam_v1_s {
6060
} recv_mam_data_id_mam_v1_t;
6161

6262
typedef struct recv_mam_key_mam_v1_s {
63-
/** Message encryption key. This field could be Pre-Shared Key (81 trytes) or NTRU public key (1024 trytes). Default:
64-
* NULL. */
65-
tryte_t* enc_key;
63+
/** Optional. The pre-shared key to decrypt the message. Each psk is in length of 81 trytes. Default: NULL. */
64+
UT_array* psk_array;
65+
/** Optional. The NTRU Secret key to decrypt the message. Each psk is in length of 1024 trytes. Default: NULL. */
66+
UT_array* ntru_array;
6667
} recv_mam_key_mam_v1_t;
6768

6869
/**
6970
* Set the data ID for MAMv1
7071
*
71-
* @param[in] req Response data in type of ta_recv_mam_req_t object
72-
* @param[in] bundle_hash Bundle hash of the message
73-
* @param[in] chid Channel ID of the messages
74-
* @param[in] msg_id Message ID of the message
72+
* @param req[in] Response data in type of ta_recv_mam_req_t object
73+
* @param bundle_hash[in] Bundle hash of the message
74+
* @param chid[in] Channel ID of the messages
75+
* @param msg_id[in] Message ID of the message
7576
*
7677
* @return
7778
* - struct of ta_recv_mam_req_t on success
@@ -82,16 +83,27 @@ status_t recv_mam_set_mam_v1_data_id(ta_recv_mam_req_t* req, char* bundle_hash,
8283
/**
8384
* Set the key for MAMv1
8485
*
85-
* @param[in] req Response data in type of ta_recv_mam_req_t object
86-
* @param[in] psk Pre-Shared Key to decrypt message
87-
* @param[in] ntru NTRU public key to decrypt message
86+
* @param req[in] Response data in type of ta_recv_mam_req_t object
87+
* @param psk[in] Pre-Shared Key to decrypt message
88+
* @param ntru[in] NTRU public key to decrypt message
8889
*
8990
* @return
9091
* - struct of ta_recv_mam_req_t on success
9192
* - NULL on error
9293
*/
9394
status_t recv_mam_set_mam_v1_key(ta_recv_mam_req_t* req, tryte_t* psk, tryte_t* ntru);
9495

96+
/**
97+
* Initialize 'ta_recv_mam_req_t' object as MAMv1 object
98+
*
99+
* @param req[out] ta_recv_mam_req_t object to be initialized
100+
*
101+
* @return
102+
* - struct of ta_recv_mam_req_t on success
103+
* - NULL on error
104+
*/
105+
status_t recv_mam_req_v1_init(ta_recv_mam_req_t* req);
106+
95107
#ifdef __cplusplus
96108
}
97109
#endif

0 commit comments

Comments
 (0)